Welcome to the Treehouse Community

Want to collaborate on code errors? Have bugs you need feedback on? Looking for an extra set of eyes on your latest project? Get support with fellow developers, designers, and programmers of all backgrounds and skill levels here with the Treehouse Community! While you're at it, check out some resources Treehouse students have shared here.

Looking to learn something new?

Treehouse offers a seven day free trial for new students. Get access to thousands of hours of content and join thousands of Treehouse students and alumni in the community today.

Start your free trial

Python Django Class-based Views Customizing Class-based Views Overriding Methods

Code challenge: Overriding get_queryset method in generic ListView for Article

I've tried several different approaches but have yet to successfully complete the following code challenge:

"I want to be able to search for articles with a certain term in their body. In the ArticleSearch view, override the get_queryset method and return any Articles where the body contains self.kwargs["term"]. Make sure it's a case-insensitive search. Oh, and the term could be blank, so handle that case, too, and return zero records."

Here's what my code looks like at this point:

from django.views import generic

from . import models


class ArticleList(generic.ListView):
    model = models.Article


class ArticleDetail(generic.DetailView):
    model = models.Article


class ArticleCreate(generic.CreateView):
    fields = ('title', 'body', 'author', 'published')
    model = models.Article


class ArticleUpdate(generic.UpdateView):
    fields = ('title', 'body', 'author', 'published')
    model = models.Article


class ArticleDelete(generic.DeleteView):
    model = models.Article


class ArticleSearch(generic.ListView):
    model = models.Article

    def get_queryset(self):
        qs = super(ArticleSearch, self).get_queryset()
        filtered = qs.filter(body__icontains = self.kwargs["term"])
        if self.kwargs['term'] = '':
            return qs.none()
        elif filtered in qs:
            return filtered
        else:
            return qs.none()

Does anyone happen to know what I'm missing?

[MOD: Added ```python formatting -cf]

4 Answers

All the docs seem to make it more confusing than it actually is. This is what worked for me, short and sweet.

def get_queryset(self):
        term = self.kwargs["term"]
        if term:
            return self.model.objects.filter(body__icontains=term)
        return self.model.objects.none()

Moderator Edited: Added language id to markdown for syntax highlighting and move from "comment" section to the "Answers"

Josh's solution works fine, especially for the challenge. But the more standard way is to call the super() so as not to loose other functionalities offered by the original method.

    def get_queryset(self):
        queryset = super().get_queryset()
        term = self.kwargs.get('term')
        if term:
            return queryset.filter(body__icontains=term)
        return queryset.none()

That worked perfectly! Thanks Josh!

James Peabody
PLUS
James Peabody
Courses Plus Student 1,825 Points

Not adding much value for those seeking correctness but adding a thought experiment for performance.

    def get_queryset(self):
        query set = super().get_queryset()
        if self.kwargs.get('term'):
            return queryset.filter(body__icontains=self.kwargs['term'])
        return queryset.none()

The advantages of the above code are:

  1. Captures the very good points raised by Jasper Maposa.
  2. Fewer lines of execution.
  3. The line that is removed is the construction and assignment of a new local variable, a variable that falls out of scope almost immediately and is created regardless of use or outcome. Therefore avoiding the construction costs of term is an advantage.
  4. Conforms a little to the DRY programming methodology if only as a percentage of the size of the passage rather than the actual gain. The code doesn't duplicate the contents of a variable.

The disadvantages of the above code are:

  1. It is a slightly more terse to read, particularly for newer programmers.
  2. Access to data inside of a structure slower than to a simple object. Not a significant disadvantage given the construction cost of term and that value access within a DICT() using key access represents a very small cost.