Max Loyd
Max Loyd

Reputation: 418

ListView View object has no attribute 'object'

I used to have the view as a DetailView but when I wanted to add pagination I needed to change the view to a ListView. But since doing this it has started throwing this error: 'CategoryDetailView' object has no attribute 'object' I believe I need to assign category's to self but I am not 100% sure how to do this.

I have tried:

def category(self , request , *args , **kwargs):
        self.object = self.get_object()
        return self.object

But it didn't work so this is what it is at the moment.

View:

class CategoryDetailView(ListView):
    model = Category
    paginate_by = 1

    def get_context_data(self, **kwargs):
        context = super(CategoryDetailView, self).get_context_data(**kwargs)
        context['category_posts'] = Post.objects.filter(live=True, category=self.object)
        return context

Thanks guys

Upvotes: 3

Views: 3078

Answers (1)

willeM_ Van Onsem
willeM_ Van Onsem

Reputation: 476669

Using a DetailView

A ListView is used to render, well, a list of objects of the model you specify. Here however, you only want to retrieve a single Category, and the Posts of that category, you thus should use a DetailView [Django-doc]. As specified in the documentation, such view contains a self.object:

While this view is executing, self.object will contain the object that the view is operating upon.

from django.views.generic import DetailView

class CategoryDetailView(DetailView):
    model = Category

    def get_context_data(self, **kwargs):
        context = super(CategoryDetailView, self).get_context_data(**kwargs)
        context['category_posts'] = self.object.post_set.filter(live=True)
        return context

it furthermore does not make much sense to use a paginate_by attribute, since a DetailView of course always renders exactly one element.

In the URL, you probably specify a parameter named pk, or a parameter named slug (given a Category has a slug field). The DetailView will automatically retrieve the Category that corresponds with this pk/slug.

Using a ListView

Alternatively, you can use a ListView, but in that case a ListView of Posts. Indeed, we can construct such ListView like:

from django.views.generic import ListView

class CategoryDetailView(ListView):
    model = Post
    paginate_by = 20

    def get_queryset(self):
        return super().get_queryset().filter(category__id=self.kwargs['pk'])

    def get_context_data(self, **kwargs):
        context = super().get_context_data(**kwargs)
        context['category'] = Category.objects.get(id=self.kwargs['pk'])
        return context

So here we can fetch the relavant Category by accessing the pk in the URL parameters. We here implement the listview however over the Posts.

Upvotes: 2

Related Questions