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 trialJonas Davidson
4,654 PointsCode 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
Josh Roberts
9,930 PointsAll 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"
Jasper Maposa
26,918 PointsJosh'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()
Jonas Davidson
4,654 PointsThat worked perfectly! Thanks Josh!
James Peabody
Courses Plus Student 1,825 PointsNot 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:
- Captures the very good points raised by Jasper Maposa.
- Fewer lines of execution.
- 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. - 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:
- It is a slightly more terse to read, particularly for newer programmers.
- 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.