django的URL Conf是否支持将参数映射到字符串?

时间:2016-07-26 15:43:11

标签: python django

问题

我不确定用这句话的最佳方法,但是这里有:(请注意,其中一些可能在语法/语义上不正确,因为它不是我的实际代码,但我需要它帮助解释我要求的内容

假设我有一个模型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)

我想为各种类型的专辑分别设置网址。目前,URL Conf就像这样:

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"),
]

当我想提供相应的网址时,我需要手动检查album_type

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)

但是,这很麻烦,我想知道是否有办法将album_type字段传递给reverse,并让它自动获取基于网址的广告在那。就像这样:

urlpatterns = [
    url(r'^(?P<type>[singles|demos|greatest-hits])/(?P<pk>.+)/$', views.AlbumView, name="albums"),
]

并使用

进行调用
reverse("albums", object.album_type, object.id)

尝试解决方案

我考虑过将选择字符串设置为

ALBUM_CHOICES = (
    (ALBUM_TYPE_SINGLE, 'singles'),
    (ALBUM_TYPE_DEMO, 'demos'),
    (ALBUM_TYPE_GREATEST_HITS, 'greatest-hits'),
)

然后允许我发送object.get_album_type_display()作为字符串变量的类型,但是,我需要能够使用reverse来构建URL,同时只能访问整数album_type的值,而不是显示值。

我知道这对于一个奇怪的特定场景来说是一个奇怪的具体问题,但如果有人有任何潜在的解决方案,我将非常感激!提前谢谢!

1 个答案:

答案 0 :(得分:2)

我会将字段更改为CharField,并使用URL slug作为实际值而不是显示值:

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)

urls.py

urlpatterns = [
    url(r'^(?P<type>singles|demos|greatest-hits)/(?P<pk>.+)/$', views.AlbumView, name="albums"),
]

然后你可以通过传递album.album_type来反转它:

reverse('albums', args=(album.album_type, album.pk))