Django 2 by Example
上QQ阅读APP看书,第一时间看更新

Creating a comment system

Now, we will build a comment system for the blog, wherein the users will be able to comment on posts. To build the comment system, you will need to do the following steps:

  1. Create a model to save comments
  2. Create a form to submit comments and validate the input data
  3. Add a view that processes the form and saves the new comment to the database
  4. Edit the post detail template to display the list of comments and the form to add a new comment

First, let's build a model to store comments. Open the models.py file of your blog application and add the following code:

class Comment(models.Model): 
post = models.ForeignKey(Post,
on_delete=models.CASCADE,
related_name='comments')
name = models.CharField(max_length=80)
email = models.EmailField()
body = models.TextField()
created = models.DateTimeField(auto_now_add=True)
updated = models.DateTimeField(auto_now=True)
active = models.BooleanField(default=True)

class Meta:
ordering = ('created',)

def __str__(self):
return 'Comment by {} on {}'.format(self.name, self.post)

This is our Comment model. It contains ForeignKey to associate the comment with a single post. This many-to-one relationship is defined in the Comment model because each comment will be made on one post, and each post may have multiple comments. The related_name attribute allows us to name the attribute that we use for the relation from the related object back to this one. After defining this, we can retrieve the post of a comment object using comment.post and retrieve all comments of a post using post.comments.all(). If you don't define the related_name attribute, Django will use the name of the model in lowercase, followed by _set  (that is, comment_set) to name the manager of the related object back to this one.

You can learn more about many-to-one relationships at https://docs.djangoproject.com/en/2.0/topics/db/examples/many_to_one/.

We have included an active boolean field that we will use to manually deactivate inappropriate comments. We use the created field to sort comments in a chronological order by default.

The new Comment model you just created is not yet synchronized into the database. Run the following command to generate a new migration that reflects the creation of the new model:

python manage.py makemigrations blog

You should see the following output:

Migrations for 'blog':
blog/migrations/0002_comment.py
- Create model Comment

Django has generated a 0002_comment.py file inside the migrations/ directory of the blog application. Now, you will need to create the related database schema and apply the changes to the database. Run the following command to apply existing migrations:

python manage.py migrate

You will get an output that includes the following line:

Applying blog.0002_comment... OK 

The migration we just created has been applied, and, now, a blog_comment table exists in the database.

Now, we can add our new model to the administration site in order to manage comments through a simple interface. Open the admin.py file of the blog application, import the Comment model, and add the following ModelAdmin class:

from .models import Post, Comment

@admin.register(Comment)
class CommentAdmin(admin.ModelAdmin):
list_display = ('name', 'email', 'post', 'created', 'active')
list_filter = ('active', 'created', 'updated')
search_fields = ('name', 'email', 'body')

Start the development server with the python manage.py runserver command and open http://127.0.0.1:8000/admin/ in your browser. You should see the new model included in the BLOG section, as shown in the following screenshot:

The model is now registered in the admin site, and we can manage Comment instances using a simple interface.