教程
avatar of this article's author EarlGrey
Django
Django学习与实战(六):文章评论

本文为Django学习小组授权原创发布,首发于编程派微信公众号:编程派(微信号:codingpy)是一个专注Python编程的公众号,每天更新有关Python的国外教程和优质书籍等精选干货,欢迎关注。

通过前五周的时间我们开发了一个简单的个人 Blog,本周我们将实现 blog 文章的评论功能。

实现思路

首先需要为评论(Comment)设计一个数据库表,并编写相应的 Model,将评论与文章关联,再编写发表评论的视图,设置相应的 url 即可。

评论的 Model 设计

blog/models.py

class BlogComment(models.Model):
    user_name = models.CharField('评论者名字', max_length=100)
    user_email = models.EmailField('评论者邮箱', max_length=255)
    body = models.TextField('评论内容')
    created_time = models.DateTimeField('评论发表时间', auto_now_add=True)
    article = models.ForeignKey('Article', verbose_name='评论所属文章', on_delete=models.CASCADE)

    def __str__(self):
        return self.body[:20]

参照大部分博客评论的样式,我们的 BlogComment Model 包含这些字段:

user_name:用户在评论前先要填写他们想使用的昵称

user_email:用户在评论前先要填写他们想使用的邮箱

body:用户提交的评论内容

created_time:评论提交时间

article:评论关联的文章,因为一个评论只能关联某一篇文章,而一篇文章下可能有多个评论,因此是一对多的关系,使用 ForeignKey

评论的表单

表单用来给服务器后台提交用户填写的数据,例如平时我们看到的填写登录、注册信息的页面就是一个登录、注册表单,用户填写表单信息后,点击提交按钮,表单中填写的内容就会打包发送给服务器后台。我们需要为用户填写评论设置一个表单,django 的 form 模块为我们提供了自动生成表单的功能,如果对表单不熟悉请参阅:官方文档:表单概述 ,以了解基本的表单使用方法(如果你对表单感觉很陌生的话)。

下面我们使用 Django 的 ModelForm ( django ModelForm 介绍 )类为我们自动生成表单。首先在 blog 目录下新建一个 forms.py (和 models.py 同一目录)文件用来存放 form 的代码:

blog/forms.py

from django import forms
from .models import Article, BlogComment


class BlogCommentForm(forms.ModelForm):
    class Meta:
        """指定一些 Meta 选项以改变 form 被渲染后的样式"""
        model = BlogComment # form 关联的 Model

        fields = ['user_name', 'user_email', 'body']
        # fields 表示需要渲染的字段,这里需要渲染user_name、user_email、body
        # 这样渲染后表单会有三个文本输入框,分别是输入user_name、user_email、body的输入框

        widgets = {
            # 为各个需要渲染的字段指定渲染成什么html组件,主要是为了添加css样式。
            # 例如 user_name 渲染后的html组件如下:
            # <input type="text" class="form-control" placeholder="Username" aria-describedby="sizing-addon1">

            'user_name': forms.TextInput(attrs={
                'class': 'form-control',
                'placeholder': "请输入昵称",
                'aria-describedby': "sizing-addon1",
            }),
            'user_email': forms.TextInput(attrs={
                'class': 'form-control',
                'placeholder': "请输入邮箱",
                'aria-describedby': "sizing-addon1",
            }),
            'body': forms.Textarea(attrs={'placeholder': '我来评两句~'}),
        }

视图函数

这里我们一如既往坚持使用基于类的通用视图,由于涉及到评论表单的提交处理,因此我们使用 FormView。这里对 FormView 的使用稍作讲解。

在 Django 的基于函数的视图中,涉及表单的处理的视图其逻辑一般是这样的:

def post_comment(request):
    if request.method =='POST':
        form = BlogCommentForm(request.POST)
        if form.is_valid():
            ...
        else:
            ...
     else:
        ...

即,首先判断用户是否通过表单 POST 了数据过来,如果是,则根据 POST 过来的数据构建一个表单,如果数据验证合法(form.is_valid),则创建评论,否则返回表单提交页。如果没有 POST 数据,则做其他相应的事情。FormView 把这些逻辑做了整合,无需写那么多 if else 语句:

blog/views.py

from django.views.generic.edit import FormView

...

class CommentPostView(FormView):
    form_class = BlogCommentForm # 指定使用的是哪个form
    template_name = 'blog/detail.html'
    # 指定评论提交成功后跳转渲染的模板文件。
    # 我们的评论表单放在detail.html中,评论成功后返回到