Search code examples
pythondjangoclassdjango-generic-views

Django Generic Views: How to assign a new property?


I'm new to Python and trying to figure out Django 1.3's class-based generic views. Right now, I have the following view which gets a list of Location objects in a Category:

class category_detail(ListView):
    """Return a generic view of locations in a category."""

    def get_context_data(self, **kwargs):
        # Call the base implementation first to get a context.
        context = super(category_detail, self).get_context_data(**kwargs)
        # Add the current category to the context.
        category = get_object_or_404(Category, slug=self.kwargs['slug'])
        context['category'] = category
        return context

    def get_queryset(self):
        category = get_object_or_404(Category, slug=self.kwargs['slug'])
        return Location.objects.filter(category=category)

It does what I want it to do. But you can see that I'm repeating myself by defining category twice. Is there a way I can add a new property to the class called category that I define once at the top, and then just reference self.category in get_queryset() and get_context_data()?


Solution

  • I think you should approach it from a different angle: you should not be using ListView showing the Locations of a Category but a DetailView of a Category that also includes the Locations of that category. The name of your view class also suggests that you're showing a detail view of a category. I think it should look more like this:

    class CategoryLocationsView(DetailView):
        model = Category
        context_object_name = 'category'
    
        def get_context_data(self, **kwargs):
            context = super(CategoryLocationsView, self).get_context_data(**kwargs)
            context['location_list'] = self.get_object().location_set.all()
            return context
    

    You now have both the category and the list of locations in your context which you can use in the template.