Django spam protection (1 year, 11 months ago)

Saturday, 7 October 2006, 13:39 p.m.
Tags: { django python spam }

After one or two months of online service i started getting few spams from the freecomments. Following b-list post i will make a step by step summary to add spam protection to free comment with Akismet.

API key

You need an akismet API key, for comments to be checked again the akismet database. Get it here, you will receive an email from wordpress with the key in it.

Akismet python

Get akismet python implementation, A zip file by Michael Foord of Voidspace. Download the zip file and only extract akismet.py.

Install Akismet

To install akismet.py move the file to your site-packages directory (/usr/lib/python2.4/) folder for linux. If you are using dreamhost and fcgi, go to your website folder (not the django one) and edit django.fcgi to add

sys.path += ['/home/yourlogin/afolder_where_akismet.py_is']

Edit your project settings.py and add the api key as follow.

AKISMET_API_KEY = "4weatc7b37b3"

Template

Check you comments.html template which diplay the comments, it has to check ispublic attribute since we will set ispublic to false if akismet detect the comment as spam.

{% for comment in comment_list %}
{% if comment.is_public %} 
[...]
{% endif %}
{% endfor %}

comments.py

Edit django_src/django/contrib/comments/views/comments.py,

# add needed imports
from akismet import Akismet 
from django.contrib.sites.models import Site


In the free_comment class section atound line 300, after errors = manipulator.get_validation_errors(new_data) add

# akismet check
ak_api = Akismet(key=settings.AKISMET_API_KEY, blog_url='http://%s/' % Site.objects.get(pk=settings.SITE_ID).domain)
if ak_api.verify_key():
    ak_data = { 
        'user_ip': request.META.get('REMOTE_ADDR', '127.0.0.1'), 
        'user_agent': request.META.get('HTTP_USER_AGENT', ''), 
        'referrer': request.META.get('HTTP_REFERER', ''), 
        'comment_type': 'comment', 
        'comment_author': new_data.get('person_name', ''), 
    } 
if ak_api.comment_check(new_data.get('comment', ''), data=ak_data, build_data=True): 
    new_data['is_public'] = False 
else: 
    new_data['is_public'] = IS_PUBLIC in option_list

Feeds

If you also use comments feed, edit your feed.py and change this line:

#return FreeComment.objects.order_by('-submit_date',)[:5] to
return FreeComment.objects.filter(is_public = True).order_by('-submit_date',)[:5]
return FreeComment.objects.filter(is_public = True).order_by('-submit_date',)[:5]

Other changes you may need

Everywhere you were using FreeComment.objects, you need to add the filter(is_public = True). In my case it was in blog.py templatetags.

    def render(self, context):
    ctype = ContentType.objects.get(name='entry')
    context['blog_comments'] = FreeComment.objects.filter(content_type=ctype.id, is_public = True).order_by('-submit_date')[:5]
    return '

and blog models, with get_comment_count method.

def get_comment_count(self):
    from django.contrib.contenttypes.models import ContentType
    from django.contrib.comments.models import FreeComment
    ctype = ContentType.objects.get(name__exact='entry')
    num_comments = FreeComment.objects.filter(content_type=ctype.id, is_public = True, object_id=self.id).count()
    return num_comments

Comments

  1. Oct 22 2006
    germany
    #1

    n1!

  2. Apr 17 2007
    united kingdom
    #2

    Do you do any cleanup of spam comments, or do they remain in the database?

  3. Aug 29 2007
    united kingdom
    #3

    Bob

  4. Apr 12 2008
    france
    #4

    obviously my askimet use is broken, i stop comments for now.

  5. Aug 9 2008
    mexico
    #163

    Jonny was here tight preteens hopmoh

Post yours


Tag Cloud

Archives

Last Comments

Rss Feeds