Tutorial2¶
This tutorial guides you through the steps to use every feature of django-comments-xtd together with the Django Comments Framework. The Django project used throughout the tutorial is available to download. Following the tutorial will take over half an hour, but it is highly recommended to get a comprehensive understanding of django-comments-xtd.
Table of Contents
Introduction¶
Through the following sections the tutorial will cover the creation of a simple blog, with stories and quotes, to which we will add comments, exercising each and every feature provided by both, django-comments and django-comments-xtd, from comment post verification by mail to comment moderation and nested comments.
Preparation¶
Before we install any package we will set up a virtualenv and install everything we need in it.
$ virtualenv venv $ source venv/bin/activate (venv)$ pip install django-comments-xtd
By installing django-comments-xtd we install all its dependencies, Django and django-contrib-comments among them. So we are ready to create our project.
New project¶
Let’s start by creating a new django project:
(venv)$ django-admin.py startproject tutorial (venv)$ cd tutorial
And the blog application:
(venv)$ python manage.py startapp blog
We have to add the new blog
application along with django_comments
and django_comments_xtd
to INSTALLED_APPS
. We also need to be sure that the sites
framework is installed. Then we have to connect django_comments
with django_comments_xtd
and configure Django mailer settings.
Edit the settings file, tutorial/settings.py
, and make the following changes:
SITE_ID = 1 INSTALLED_APPS = [ ... 'django.contrib.contentypes', 'django.contrib.sessions', 'django.contrib.sites', # Be sure you have the sites app installed. ... 'django_comments_xtd', 'django_comments', 'blog', ] ... COMMENTS_APP = 'django_comments_xtd' # Either enable sending mail messages to the console: EMAIL_BACKEND = 'django.core.mail.backends.console.EmailBackend' # Or set up the EMAIL_* settings so that Django can send emails: EMAIL_HOST = "smtp.mail.com" EMAIL_PORT = "587" EMAIL_HOST_USER = "alias@mail.com" EMAIL_HOST_PASSWORD = "yourpassword" EMAIL_USE_TLS = True DEFAULT_FROM_EMAIL = "Helpdesk <helpdesk@yourdomain>"
In order to make django-comments-xtd request comment confirmation by mail we need to set the COMMENTS_XTD_SALT
setting. This setting helps obfuscating the comment before the user has approved its publication.
This is so because django-comments-xtd does not store comments in the server before they have been confirmed. This way there is little to none possible comment spam flooding in the database. Comments are encoded in URLs and sent for confirmation by mail. Only when the user clicks the confirmation URL the comment lands in the database.
This behaviour is disabled for authenticated users, and can be disabled for anonymous users too by simply setting COMMENTS_XTD_CONFIRM_MAIL
to False
.
Now let’s append the following entry to the settings module to help obfuscating the comment before it is sent for confirmation:
COMMENTS_XTD_SALT = (b"Timendi causa est nescire. " b"Aequam memento rebus in arduis servare mentem.")
Blog app modules¶
For the purposes of this tutorial we will create a model Story
within the blog
app. We will also add the modules for the admin interface, the views, the url module and some templates.
Let’s start by editing the blog/models.py
file.
from datetime import datetime import django from django.db import models from django.db.models import permalink class PublicManager(models.Manager): """Returns published stories that are not in the future.""" def published(self): return self.get_queryset().filter(publish__lte=datetime.now()) class Story(models.Model): """Story that accepts comments.""" title = models.CharField('title', max_length=200) slug = models.SlugField('slug', unique_for_date='publish') body = models.TextField('body') allow_comments = models.BooleanField('allow comments', default=True) publish = models.DateTimeField('publish', default=datetime.now) objects = PublicManager() class Meta: ordering = ('-publish',) def __str__(self): return self.title @permalink def get_absolute_url(self): return ('stories-story-detail', (), {'year': self.publish.year, 'month': int(self.publish.strftime('%m').lower()), 'day': self.publish.day, 'slug': self.slug})
We are ready to create the initial migration for the blog
, after which we run the migrate command:
(venv)$ python manage.py makemigrations blog (venv)$ python manage migrate
Let’s add admin classes to both models. Edit blog/admin.py
and add the following content:
from django.contrib import admin from blog.models import Story @admin.register(Story) class StoryAdmin(admin.ModelAdmin): list_display = ('title', 'publish', 'allow_comments') list_filter = ('publish',) search_fields = ('title', 'body') prepopulated_fields = {'slug': ('title',)} fieldsets = ((None, {'fields': ('title', 'slug', 'body', 'allow_comments', 'publish',)}),)
After editing the admin module we can use the admin interface to add instances for our new model. Let’s create first a superuser for our project:
(venv)$ python manage.py createsuperuser Username (leave blank to use 'user'): admin Email address: admin@example.com Password: Password (again): Superuser created successfully.
Now run the development server, visit http://localhost:8000/admin/ and add a sample story:
(venv)$ python manage.py runserver
Before we are ready to see the story published we still need to add the view, templates and the urls. Edit the blog/views.py
file and add the following detail view:
from django.core.urlresolvers import reverse from django.views.generic import DateDetailView from tutorial.blog.models import Story class StoryDetailView(DateDetailView): model = Story date_field = "publish" month_format = "%m" def get_context_data(self, **kwargs): context = super(StoryDetailView, self).get_context_data(**kwargs) context.update({'next': reverse('comments-xtd-sent')}) return context
Let’s create now the templates/blog
directory:
(venv)$ mkdir -p templates/blog
The templates directory will contain three files, base.html
, blog/story_list.html
and blog/story_detail.html
. Let’s start creating the base.html