Disclaimer:
This post was actually started about 9 months ago and never finished, so I’m not sure if the code will even run on the latest version of Django. I’m actually doing Ruby on Rails work nowadays at my job, and using Django solely for my personal projects. With that said, I hope some people out there will find some of these techniques somewhat useful.
—————————————————————-
Search
One feature that is commonly used on a lot of Django applications is the ability to search through content by keywords. There are many different ways to do this, but I’d like to present a way that’s super easy to implement and uses only the Django model API.
Before I start, I’d like to first give a little disclaimer: this is absolutely NOT the most efficient way to perform a search through data. If you’re looking for a more advanced solution, check out djangosearch on google code.
Ok, let’s say you’re making a blogging application, and you need a way to search blog entries for certain keywords. You may have a model named BlogEntry that looks like this:
class BlogEntry(models.Model):
blog = models.ForeignKey(Blog)
subject = models.CharField(max_length=100)
body = models.TextField()
Now let’s say you needed a way to search the ‘body’ and ‘subject’ fields of all BlogEntries for the keywords ‘Django’ and ‘Python.’ Given a set of BlogEntries, this function will search their subject and body fields for the specified keywords. Here’s how you would build the function:
def search_keywords(blogentries, keywords):
'''
Searches a given QuerySet and returns a
QuerySet that contains any word in the list of keywords
'''
if isinstance(keywords, str):
keywords = [keywords]
if not isinstance(keywords, list):
return None
list_body_qs = [Q(body__icontains=x) for x in keywords]
list_subj_qs = [Q(subject__icontains=x) for x in keywords]
final_q = reduce(operator.or_, list_body_qs + list_subj_qs)
r_qs = blogentries.filter(final_q)
return r_qs
The beginning of the function is pretty straightforward. The interesting part is the latter half of the function, which uses Django’s database API and Python’s reduce function to dynamically create a Django query with all of the keywords in it.
First, build a couple lists of Q objects, one for each keyword and field.
... list_body_qs = [Q(body__icontains=x) for x in keywords] list_subj_qs = [Q(subject__icontains=x) for x in keywords] ---
Using Python’s reduce function, we glue all these Q objects together with operator.or_.
... final_q = reduce(operator.or_, list_body_qs + list_subj_qs) r_qs = blogentries.filter(final_q) return r_qs ---
Essentially, you create a query similar to this:
Q(body__icontains=”dog”) | Q(body__icontains=”cat”) | Q(body__icontains=”parrot”) …
If you wanted to perform an all-inclusive search (i.e. AND’ing the search terms together instead of OR’ing them), you’d use operator.and_ instead of operator.or_
Finish
And that’s it. Just a few lines of code and you’ve got your own search function. Leave a comment with your thoughts
(Unless you’re a spam bot)

The Dark Side of Code Commenting
Ever since the beginning of my journey to become a solid programmer, it was taught to me that commenting code was always a good thing. You can never have enough comments, they would say. The golden rule was to have at least an equal comments to code line ratio.
All of this made sense to me back in college. Nothing wrong with being too descriptive right? Wrong! Sure, comments can be a great thing. There’s nothing better than reading a comment that helps you understand some complex piece of code. However, after working in the industry for awhile, I’ve seen the dark side of comments.
The other day, while working on one of many bugfixes, I came across an obfuscated piece of code. Instead of diving into it and figuring out where each function/variable/whatever came from, I trusted a couple lines of comments above the code. Thank god for comments, right! Wrong again! Apparently, whoever wrote that code wrote it over someone else’s code, but hadn’t updated the comment because he hadn’t noticed it. So the comment was downright false. A lie. Imagine dealing with that all day. Ever try to understand thousands of lines of code where some comments are leading you down the wrong path, like satan?
My thinking is, keep the comments to a minimum. Instead of commenting excessively, try to write your code in such a way that it doesn’t *need* too many comments to understand. Good code speaks for itself
And don’t be lazy, always update the comments as needed as your code changes. If you come across a useless one, throw it out… like a leper!
Because I’ve been getting some weird feedback on this post (my fault most likely, for being a professional programmer and not a writer), let me reiterate my point here…comments, when used appropriately, are a good thing! The key word is appropriately. Don’t diarrhea all over your code. It’s stinky. And too many people do it. When a developer sees a piece of code, he tries to understand. When he reads a comment, he is inclined to believe it right off the bat. So don’t mess with his head. Get it?
Oh and hey, leave some “comments” below if you’ve had bad experiences too