Blog Spam Protection

Posted by Ross Poulton on Sat 13 January 2007 #geeky #django #programming

I currently manually review and delete comment spam every few days. It doesn't take long, it's just frustrating.

When you regularly repeat an action over a long period of time, you begin to notice patterns of action. What I've noticed is that most comment spam is being posted to older blog posts - most likely due to their higher number of in-links, and I'm guessing higher google page rank.

To this end, what I've done is add a method to my blog Post model, which checks the post date and, if it's within the defined timeframe, will return 'True'. My Post detail template now checks this method and only displays the form when appropriate.

The first file to change is your blog applications models.py. At the top of the file add this import statement to bring in the 'datetime' module and required tools:

    from datetime import datetime, timedelta

Next, in the same file, add the following method to your 'Post' class (just after the 'body' field is fine):

        def allow_comments(self):
            return (self.date + timedelta(21)) > datetime.now()

Lastly, open up your blog detail template and replace the existing call to {% free_comment_form ... %} with:

    {% if object.allow_comments %}
    {% free_comment_form for blog.post object.id %}
    {% else %}
    <p>Comments can only be posted for recent articles.</p>
    {% endif %}

What this does is pretty straightforward. Using datetime and timedelta objects, we ensure that only posts within the last 21 days can have comments posted to them. For me, this timespan works well, you may need to experiment with longer or shorter times.

Next up for me is actually altering the 'comments' mechanism to add filtering via Akismet or similar processes - but I'm wary of modifying the contrib code as I dread upgrade-time!