我有一个名为Label的模型:
class Label(models.Model):
"""The label a song was released on."""
name = models.CharField(max_length=100)
def __str__(self):
"""String for representing the model object."""
return self.name
我正在为每个标签的单个模型实例定义url路径:
# Page for a single label.
path('labels/<int:label_id>/', views.label, name='label'),
是否可以在URL路径中使用label.name属性而不是int:label_id?该怎么办?
这是views.py中的相应代码:
def label(request, label_id):
"""Show a single label and associated songs."""
label = Label.objects.get(id=label_id)
context = {'label': label}
return render(request, 'great_songs_app/label.html', context)
答案 0 :(得分:1)
是的,您可以更改传入参数的名称和url:
# Page for a single label.
path('labels/<str:name>/', views.label, name='label'),
def label(request, name):
try:
label = Label.objects.get(name=name)
except Label.MultipleObjectsReturned:
label = None # TODO have a strategy
请注意,由于您要键入一个非唯一参数,因此可能会发生冲突。另外,您有一个非常开放的CharField,其中可能包含空格,斜杠等。更好的方法是使用一个显式的“ SlugField”来生成该段代码:
class Label(models.Model):
name = models.CharField(max_length=100)
slug = models.SlugField()
然后您可以将此SlugField设置为预先填充到您的管理文件(docs)中:
class LabelAdmin(admin.ModelAdmin):
prepopulated_fields = {"slug": ("name",)}
最后,我会强烈考虑为此使用DetailView,在该处,您可以获得“免费”的许多预定义功能:
from django.views.generic.detail import DetailView
class LabelDetailView(DetailView):
queryset = Label.objects.all()
slug_field = 'slug' # Or Name, Or Id
slug_url_kwargs = 'slug' # Or name or label_id
答案 1 :(得分:0)
从本质上讲是一样的,您只需将int
(=字符串)的str
和id
的{{1}}切换:
网址:
name
视图:
path('labels/<str:label_name>/', views.label, name='label')
添加def label(request, label_name):
l = Label.objects.get(name=label_name)
…
以防止冲突是明智的。
如果您打算使用带有空格或其他非URL友好的字符的名称,则可能要使用slug作为URL部分:
unique=True
使用子弹作为主键也很方便。