I'm unsure of the best way to phrase this, but here goes: (note some of this may not be syntactically/semantically correct, as it's not my actual code, but I needed it to help explain what I'm asking)
Say I have a model the model Album
:
Class Album(models.Model):
ALBUM_TYPE_SINGLE = 1
ALBUM_TYPE_DEMO = 2
ALBUM_TYPE_GREATEST_HITS = 3
ALBUM_CHOICES = (
(ALBUM_TYPE_SINGLE, 'Single Record'),
(ALBUM_TYPE_DEMO, 'Demo Album'),
(ALBUM_TYPE_GREATEST_HITS, 'Greatest Hits'),
)
album_type = models.IntegerField(choices=ALBUM_CHOICES)
And I want to have separate URLs for the various types of albums. Currently, the URL Conf is something like so:
urlpatterns = [
url(r'^singles/(?P<pk>.+)/$', views.AlbumView, name="singles"),
url(r'^demos/(?P<pk>.+)/$', views.AlbumView, name="demos"),
url(r'^greatest-hits/(?P<pk>.+)/$', views.AlbumView, name="greatest_hits"),
]
And when I want to serve the appropriate URL, I need to check the album_type
manually:
if object.album_type == Album.ALBUM_TYPE_SINGLE:
return reverse('singles', object.id)
elif object.album_type == Album.ALBUM_TYPE_DEMO:
return reverse('demos', object.id)
elif object.album_type == Album.ALBUM_TYPE_GREATEST_HITS:
return reverse('greatest_hits', object.id)
However, this is cumbersome to do, and I'm wondering if there is a way to pass in the album_type
field to the call to reverse
and have it automatically get the URL based on that. ie something like this:
urlpatterns = [
url(r'^(?P<type>[singles|demos|greatest-hits])/(?P<pk>.+)/$', views.AlbumView, name="albums"),
]
and called with
reverse("albums", object.album_type, object.id)
I considered setting the choice strings to be
ALBUM_CHOICES = (
(ALBUM_TYPE_SINGLE, 'singles'),
(ALBUM_TYPE_DEMO, 'demos'),
(ALBUM_TYPE_GREATEST_HITS, 'greatest-hits'),
)
which would then allow me to send object.get_album_type_display()
as a string variable for type, which works, however, I need to be able to use reverse
to build the URL while only having access to the integer value of album_type
and not the display value.
I know this is an oddly specific question for an oddly specific scenario, but if anyone has any kind of potential solutions, I'd be very grateful! Thank you in advance!
I would change the field to a CharField
, and use the URL slug as the actual value rather than the display value:
Class Album(models.Model):
ALBUM_TYPE_SINGLE = 'singles'
ALBUM_TYPE_DEMO = 'demos'
ALBUM_TYPE_GREATEST_HITS = 'greatest-hits'
ALBUM_CHOICES = (
(ALBUM_TYPE_SINGLE, 'Single Record'),
(ALBUM_TYPE_DEMO, 'Demo Album'),
(ALBUM_TYPE_GREATEST_HITS, 'Greatest Hits'),
)
album_type = models.CharField(choices=ALBUM_CHOICES, max_length=50)
In your urls.py
:
urlpatterns = [
url(r'^(?P<type>singles|demos|greatest-hits)/(?P<pk>.+)/$', views.AlbumView, name="albums"),
]
Then you can reverse it by passing album.album_type
:
reverse('albums', args=(album.album_type, album.pk))
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.