简体   繁体   中英

Using get_queryset() method in ListView, Django 1.9

I've been having difficulty getting ListViews to render as expected on a blog project I'm working on.

I have a Tag model, which is part of a Post model, as follows (from my Post model in models.py):

 class Post(models.Model):
    (...)
        tags = models.ManyToManyField(Tag)

TagListView in views.py is as follows:

class TagListView(ListView):
    def get_queryset(self):
        slug = self.kwargs['slug']
        try:
            tag = Tag.objects.get(slug=slug)
            return tag.post_set.all()
        except Tag.DoesNotExist:
            return Post.objects.none()

The url's is as follows (which is included in the project like though url(r'^blog/?', include('blog.urls')), , is as follows:

    url(r'^tag/(?P<slug>[a-zA-Z0-9-]+)?/?$', TagListView.as_view(
        paginate_by=5,
        model=Tag,
    )),

From what I understand, accessing a URL, which, for this example, should be at localhost:8000/blog/tag/<name-of-tag-here> , calls TagListView in views.py, which then uses the get_queryset() method to generate a ListView of posts featuring a tag with the same slug, which then looks for a template (at /blog/templates/blog ), which, in the tutorial I'm viewing, is called tag_post_list.html , but -- the documentation is unclear on how the ListView finds a template to render and I'm simply following an outdated tutorial.

I'm a bit confused about which variables are being passed into the html template and how to access them. From the results I'm getting it's clear that get_queryset() is not actually only returning posts with the same tag listing. Furthermore, my css isn't rendering, either (which I've made a separate post for) , despite it being plainly obvious that other tags and elements from my base.html file are.

The template begins {% extends 'base.html' %} (which is located in /blog/templates/ ) and accesses posts through {% for post in object_list %} . object_list obviously does not contain what I think it should, which, as far as I understand, should be due to the the way I'm misusing ListView's get_queryset() method.

Thanks.

There are a lot of questions to unpack here. A couple answers:

Your ListView has a template_name attribute where you can specify the template to use, like so:

class TagListView(ListView):

    template_name = "tag_post_list.html"

    def get_queryset(self):
        slug = self.kwargs['slug']
        try:
            tag = Tag.objects.get(slug=slug)
            return tag.post_set.all()
        except Tag.DoesNotExist:
            return Post.objects.none()

See this site for a quick list of available attributes for your class based views.

Second answer - you're saying that:

tag = Tag.objects.get(slug=slug)
return tag.post_set.all()

...in your view isn't actually returning the correct Post objects. It's not clear from your code why this is the case. Your view appears correct, though as Daniel Roseman pointed out it should probably be based on the model Post , not Tag . Overriding the get_queryset method to return Post objects though means this isn't the offending issue. It's possible that fixing the first issue actually fixes the second, because object_list never got called because the template wasn't being called...

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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM