Django - 包含模板的多个 url 参数
Django - multiple url params with included template
我正在尝试包含一个模板并在两个不同的视图中使用它,其中第一个获得一个 url 参数,第二个获得相同的参数加上另一个。在我包含的模板中有一个带有 {% url %} 标签的迭代,我需要传递这两个参数,因为第二个视图需要它们,但是这样做会在尝试呈现我的第一个视图时导致 NoReverseMatch,可能是因为它只接受一个参数。有没有办法指定第二个参数是可选的?
这是我的代码:
urls.py
...
url(r'^portfolio/(?P<category_slug>[-\w]+)/$', views.category, name='category'),
url(r'^portfolio/(?P<category_slug>[-\w]+)/(?P<album_slug>[-\w]+)/$', views.album, name='album'),
...
models.py
...
class Album(models.Model):
cover = models.ImageField()
title = models.CharField(max_length=200, unique=True)
description = models.CharField(max_length=200, blank=True)
posts = models.ManyToManyField(Post, blank=True)
slug = models.SlugField(max_length=200)
class Category(models.Model):
cover = models.ImageField()
title = models.CharField(max_length=200, unique=True)
albums = models.ManyToManyField(Album, blank=True)
slug = models.SlugField(max_length=200)
@receiver(pre_save, sender=Album)
@receiver(pre_save, sender=Category)
def save_slug(sender, instance, *args, **kwargs):
instance.slug = slugify(instance.title)
...
views.py
...
def index(request):
main_categories = Category.objects.filter(...)
return render(request, 'index.html', {'main_categories': main_categories})
def category(request, category_slug):
try:
category_selected = Category.objects.get(slug=category_slug)
except Category.DoesNotExist:
category_selected = None
albums = category_selected.albums.all()
return render(request, 'category.html', {
'category_selected': category_selected,
'albums': albums
})
def album(request, category_slug, album_slug):
try:
category_selected = Category.objects.get(slug=category_slug)
album_selected = Album.objects.get(slug=album_slug)
except Category.DoesNotExist:
category_selected = None
except Album.DoesNotExist:
album_selected = None
posts = album_selected.posts.all()
return render(request, 'album.html', {
'category_selected': category_selected,
'album_selected': album_selected,
'posts': posts
})
...
includedtemplate.html
...
{% for obj in objects %}
...
<a href="{% url view category_slug=obj.slug album_slug=obj.slug %}">
...
{% endfor %}
...
index.html
...
{% include 'includedtemplate.html' with objects=main_categories view='category' %}
...
编辑:
我设法通过将我的 urls 与每个不同的 slug 分开来解决这个问题。这更简单,更适合我的情况,考虑到我有一个 M2M 用于类别和专辑,这可能会导致单个专辑有很多 url。
您可以合并视图并为 album_slug 设置 None。
def combined_view(request, category_slug, album_slug=None):
category_selected = Category.objects.filter(slug=category_slug).first()
album_selected = None
posts = None
template = 'category.html'
if album_slug:
album_selected = Album.objects.filter(slug=album_slug).first()
posts = album_selected.posts.all()
template = 'album.html'
return render(request, template, {
'category_selected': category_selected,
'album_selected': album_selected,
'posts': posts
})
urls 的顺序也很重要 - 第一个 url 应该有一个参数,第二个有两个参数:
url(r'^portfolio/(?P<category_slug>[-\w]+)/$', views.combined_view, name='cview'),
url(r'^portfolio/(?P<category_slug>[-\w]+)/(?P<album_slug>[-\w]+)/$', views.combined_view, name='cview'),
P.S。在视图中,您可以使用 filter().first() 而不是 try..except。写起来更快。
我正在尝试包含一个模板并在两个不同的视图中使用它,其中第一个获得一个 url 参数,第二个获得相同的参数加上另一个。在我包含的模板中有一个带有 {% url %} 标签的迭代,我需要传递这两个参数,因为第二个视图需要它们,但是这样做会在尝试呈现我的第一个视图时导致 NoReverseMatch,可能是因为它只接受一个参数。有没有办法指定第二个参数是可选的?
这是我的代码:
urls.py
...
url(r'^portfolio/(?P<category_slug>[-\w]+)/$', views.category, name='category'),
url(r'^portfolio/(?P<category_slug>[-\w]+)/(?P<album_slug>[-\w]+)/$', views.album, name='album'),
...
models.py
...
class Album(models.Model):
cover = models.ImageField()
title = models.CharField(max_length=200, unique=True)
description = models.CharField(max_length=200, blank=True)
posts = models.ManyToManyField(Post, blank=True)
slug = models.SlugField(max_length=200)
class Category(models.Model):
cover = models.ImageField()
title = models.CharField(max_length=200, unique=True)
albums = models.ManyToManyField(Album, blank=True)
slug = models.SlugField(max_length=200)
@receiver(pre_save, sender=Album)
@receiver(pre_save, sender=Category)
def save_slug(sender, instance, *args, **kwargs):
instance.slug = slugify(instance.title)
...
views.py
...
def index(request):
main_categories = Category.objects.filter(...)
return render(request, 'index.html', {'main_categories': main_categories})
def category(request, category_slug):
try:
category_selected = Category.objects.get(slug=category_slug)
except Category.DoesNotExist:
category_selected = None
albums = category_selected.albums.all()
return render(request, 'category.html', {
'category_selected': category_selected,
'albums': albums
})
def album(request, category_slug, album_slug):
try:
category_selected = Category.objects.get(slug=category_slug)
album_selected = Album.objects.get(slug=album_slug)
except Category.DoesNotExist:
category_selected = None
except Album.DoesNotExist:
album_selected = None
posts = album_selected.posts.all()
return render(request, 'album.html', {
'category_selected': category_selected,
'album_selected': album_selected,
'posts': posts
})
...
includedtemplate.html
...
{% for obj in objects %}
...
<a href="{% url view category_slug=obj.slug album_slug=obj.slug %}">
...
{% endfor %}
...
index.html
...
{% include 'includedtemplate.html' with objects=main_categories view='category' %}
...
编辑: 我设法通过将我的 urls 与每个不同的 slug 分开来解决这个问题。这更简单,更适合我的情况,考虑到我有一个 M2M 用于类别和专辑,这可能会导致单个专辑有很多 url。
您可以合并视图并为 album_slug 设置 None。
def combined_view(request, category_slug, album_slug=None):
category_selected = Category.objects.filter(slug=category_slug).first()
album_selected = None
posts = None
template = 'category.html'
if album_slug:
album_selected = Album.objects.filter(slug=album_slug).first()
posts = album_selected.posts.all()
template = 'album.html'
return render(request, template, {
'category_selected': category_selected,
'album_selected': album_selected,
'posts': posts
})
urls 的顺序也很重要 - 第一个 url 应该有一个参数,第二个有两个参数:
url(r'^portfolio/(?P<category_slug>[-\w]+)/$', views.combined_view, name='cview'),
url(r'^portfolio/(?P<category_slug>[-\w]+)/(?P<album_slug>[-\w]+)/$', views.combined_view, name='cview'),
P.S。在视图中,您可以使用 filter().first() 而不是 try..except。写起来更快。