Django评论系统

目录

创建评论模型

将新模型添加到管理站点

创建一个表单来提交评论和验证输入数据

显示评论总数和评论列表

创建评论表单,当表单成功提交时,显示一条成功消息


创建评论模型

blog/models.py

python 复制代码
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)

📌related_name让我们可以使用属性命名相互关联的对象。通过Post.comments.all()检索文章所有评论。如果没有定义related_name属性,Django将使用小写的模型名,后面跟着_set (comment_set)

更新数据库

python .\\manage.py makemigrations blog

python .\\manage.py migrate

将新模型添加到管理站点

python 复制代码
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')

模型关联 API 用法示例 | Django 文档 | Django (djangoproject.com)

创建一个表单来提交评论和验证输入数据

Django有两个基类来构建表单:Form和ModelForm。之前使用了第一种方法让您的用户通过电子邮件共享帖子。关于Form类更多内容,请看Django发送QQ邮件-CSDN博客

在本例中,使用 ModelForm,因为必须从Comment模型动态地构建表单。

blog/forms.py

python 复制代码
from django import forms
from .models import Comment

#...

class CommentForm(forms.ModelForm):

    class Meta:
        model = Comment
        fields = ('name','email','body')

添加一个视图来处理表单并将新注释保存到数据库中

编辑blog/views.py

python 复制代码
from .forms import EmailPostForm,CommentForm
#...

def post_detail(request,year,month,day,post):

    post = get_object_or_404(Post,slug=post,
                             status='published',
                             publish__year=year,
                             publish__month=month,
                             publish__day=day
                             )

    comments = post.comments.filter(active=True)
    new_comment = None

    if request.method == 'POST':
        comment_form = CommentForm(data=request.POST)
        if comment_form.is_valid():
            new_comment = comment_form.save(commit=False)
            new_comment.post = post
            new_comment.save()
    else:
        comment_form = CommentForm()

    template = "blog/post/detail.html"
    context = {
        "post":post,
        "comments":comments,
        "new_comment":new_comment,
        "comment_form":comment_form
    }
  
    return render(request,template,context)

将new_comment变量设置为None。将在创建新注释时使用该变量。如果视图被GET请求调用,用comment_form = CommentForm()构建一个表单实例。如果请求是POST,使用提交的数据实例化表单,并使用is_valid()方法验证它。如果表单无效,则呈现带有验证错误的模板。

如果表单有效,通过调用表单的save()方法创建一个新的Comment对象,并将其赋值给new_comment变量

  • new_comment = comment_form.save(commit=False),save()方法创建表单链接到的模型实例,并将其保存到数据库中。如果使用commit=False,则创建了模型实例,但还没有将其保存到数据库中。
  • new_comment.post = post,当把当前的文章分配给新建的评论(post)。
  • new_comment.save(),写入数据库。

📌save()方法可用于ModelForm,但不能用于Form实例,因为它们没有链接到任何模型。

显示评论总数和评论列表

显示评论总数

/blog/templates/post/detail.html

html 复制代码
    {% with comments.count as total_comments %}
        <h2>
            {{ total_comments }} comment {{ total_comments|pluralize  }}
        </h2>
    {% endwith%}

我们在模板中使用Django ORM,执行QuerySet comments.count()。

📌注意Django模板语言不使用圆括号来调用方法。

{% with %}标签允许我们为一个新变量赋值,该变量将在{% endwith %}标签之前可用。

📌{% with %}模板标签对于避免多次访问数据库或访问昂贵的方法非常有用。

显示评论列表

/blog/templates/post/detail.html

html 复制代码
    {% for comment in comments %}
        <div class="comment">
            <p class="info">
                Comment {{ forloop.counter}} by {{ comment.name}}
                {{ comment.created }}
            </p>
            {{ comment.body|linebreaks  }}
        </div>
    {% empty %}
        <p>There are no comments yet.</p>
    {% endfor %}

使用{% for %}模板标签来循环遍历评论。如果评论列表为空,我们将显示一条默认消息,通知用户这篇文章还没有评论。{{forloop.counter}}包含每次迭代的循环计数器。然后,显示发布评论的用户的姓名、日期和评论正文。

创建评论表单,当表单成功提交时,显示一条成功消息

/blog/templates/post/detail.html

html 复制代码
    {% if new_comment %}
        <h2>Your commet has been added.</h2>
    {% else %}

        <h2>Add a new comment</h2>
        <form action="." method="post">
            {{ comment_form.as_p}}
            {% csrf_token %}
            <p>
                <input type="submit" value="Add comment">
            </p>
        </form>

    {% endif %}

如果new_comment对象存在,我们将显示一条成功消息,因为注释已成功创建。否则,将为评论模型每个字段呈现带有段落<p>元素的表单,并包含POST请求所需的CSRF令牌。

相关推荐
Chef_Chen11 分钟前
从0开始机器学习--Day17--神经网络反向传播作业
python·神经网络·机器学习
知识的宝藏23 分钟前
Django中间件应该怎么使用
中间件·django
千澜空31 分钟前
celery在django项目中实现并发任务和定时任务
python·django·celery·定时任务·异步任务
斯凯利.瑞恩38 分钟前
Python决策树、随机森林、朴素贝叶斯、KNN(K-最近邻居)分类分析银行拉新活动挖掘潜在贷款客户附数据代码
python·决策树·随机森林
yannan201903131 小时前
【算法】(Python)动态规划
python·算法·动态规划
竹笋常青1 小时前
《流星落凡尘》
django·numpy
蒙娜丽宁1 小时前
《Python OpenCV从菜鸟到高手》——零基础进阶,开启图像处理与计算机视觉的大门!
python·opencv·计算机视觉
光芒再现dev1 小时前
已解决,部署GPTSoVITS报错‘AsyncRequest‘ object has no attribute ‘_json_response_data‘
运维·python·gpt·语言模型·自然语言处理
好喜欢吃红柚子1 小时前
万字长文解读空间、通道注意力机制机制和超详细代码逐行分析(SE,CBAM,SGE,CA,ECA,TA)
人工智能·pytorch·python·计算机视觉·cnn
小馒头学python1 小时前
机器学习是什么?AIGC又是什么?机器学习与AIGC未来科技的双引擎
人工智能·python·机器学习