Django - 包含模板的多个url params

时间:2017-11-07 16:05:57

标签: python django django-templates django-urls

我试图包含一个模板并在两个不同的视图中使用它,其中第一个获取一个url参数,第二个获取相同的另一个。在我包含的模板中有一个带有{%url%}标签的迭代,我需要传递两个参数,因为第二个视图需要它们,但这样做会导致NoReverseMatch在尝试渲染我的第一个视图时,可能是因为它只接受一个PARAM。有没有办法指定第二个参数是可选的?

这是我的代码:

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' %}

...

修改 我设法通过将我的网址分别只用一个不同的slug来解决这个问题。这更简单,更适合我的情况,考虑到我有一个类别和专辑的M2M,这可能会导致一个专辑的许多网址。

1 个答案:

答案 0 :(得分:0)

您可以组合视图并为album_slug设置无。

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
    })

网址的顺序也很重要 - 第一个网址应该是一个参数,第二个是两个参数:

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在视图中。写作速度更快。