Django开发博客3

评论板块的开发

涉及知识点:

  • form表单设置css样式和输入框类型,数据清洗
  • 服务端快速接受POST请求提交的form表单数据
  • 前端模板中遍历form表单中的错误信息
  • TemplateView的使用
  • js返回上个页面
  • 自定义模板标签

1.配置评论提交时的form表单 forms.py

from comment.models import Comment
from django import forms

# 如果不考虑样式,仅需定义model和fields即可
class CommentForm(forms.ModelForm):
    # email = forms.CharField(
    #     label='Email',
    #     max_length=50,
    #     widget=forms.widgets.EmailInput(
    #         attrs={'class': 'form-control', 'style': 'width: 60%'}
    #     )
    # )
    content = forms.CharField(
        label='内容',
        max_length=500,
        # 可以在定义form表单时设置限制和样式
        widget=forms.widgets.Textarea(
            attrs={'rows': 6, 'cols': 60, 'class': 'form-control'}
        )
    )

    # 定义需要进行数据清洗的字段和规则
    def clean_content(self):
        content = self.cleaned_data.get('content')  # 获取字段内容
        if len(content) < 10:
            raise forms.ValidationError('评论不可少于10个字')
        return content

    class Meta:
        model = Comment
        fields = ['content',]    # 表单对象渲染时显示的字段

2.在Model层提供返回某篇文章下所有评论的接口

class Comment(models.Model):
	# 省略其余代码
    @classmethod
    def get_by_target(cls, target):
        return cls.objects.filter(target=target, status=cls.STATUS_NORMAL)

3. 视图层,完成提交评论功能

from comment.forms import CommentForm
from django.shortcuts import render, redirect
from django.urls import reverse
from django.views.generic import TemplateView

# 定义评论提交的视图类
class CommentView(TemplateView):
    http_method_names = ['post']    # 限定该视图类仅提供post方法
    template_name = 'comment/result.html'

    def post(self, request, *args, **kwargs):
	    # 接受POST请求提交的form表单数据
        comment_form = CommentForm(request.POST)  
        target = request.POST.get('target')

        if comment_form.is_valid():
            # 此处通过form表单对象创建了一个实例,不用再创建comment的对象了
            instance = comment_form.save(commit=False)
            instance.target = target
            instance.nickname = request.user.first_name
            instance.website = reverse('author', args=(request.user.id,))
            email = request.user.email
            instance.save()
            succeed = True
            return redirect(target)
        else:
            succeed = False
        context = {
        	# 标记是否评论成功
            'succeed': succeed,
            # 若发生异常,form表单对象中会存入异常信息
            'form': comment_form,
            'target': target,
        }
        # 将数据渲染到响应对象和模板中
        # 也可以直接用render(request, self.template_name, context=context)
        return self.render_to_response(context)

4.配置评论响应界面,评论成功则返回原文章,失败则返回指定提示页面

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>评论结果页</title>
</head>
<body>
<div class="result">
    {% if succeed %}
        评论成功!
        <a href="{{ target }}"></a>
    {% else %}
        评论失败:
        <ul class="errorlist">
            <!-- 遍历form表单中的错误信息 -->
            {% for field, message in form.errors.items %}
                <li>{{ message }}</li>
            {% endfor %}
        </ul>
        <!-- JS返回上个页面 -->
        <a href="javascript:window.history.back();">返回</a>
    {% endif %}
</div>
</body>
</html>

5.抽象出评论模板组件
1.编写自定义标签:comment APP下新建templatetags目录,目录下新增__init__.py和comment_block.py
获取数据源 comment_block.py

from django import template
from comment.forms import CommentForm
from comment.models import Comment

# 自定义模板标签
register = template.Library()
# 配置评论模板,前端页面直接当成标签渲染
@register.inclusion_tag('comment/block.html')
def comment_block(target):
    return {
        # 自定义标签中默认没有request对象,因此需要手动将target添加到页面中
        'target': target,
        'comment_form': CommentForm,
        'comment_list': Comment.get_by_target(target),
    }

2.前端模板

<div class="comment">
    <p>留言区</p>
    <form action="/comment/" method="post" class="form-group">
        {% csrf_token %}
        <input type="hidden" name="target" value="{{ target }}">
        {{ comment_form.as_p }}
        <input type="submit" value="写好了">
    </form>

    <!-- 评论列表 -->
    <p>留言板</p>
    <ul class="list-group">
        {% for comment in comment_list %}
            <li class="list-group-item">
                <div class="nickname">
                    <a href="{{ comment.website }}">
                        {% if comment.nickname %}
                        {{ comment.nickname }}
                        {% else %}
                            暂无昵称
                        {% endif %}
                    </a>
                    <span>{{ comment.created_time }}</span>
                </div>
                <div class="comment-content">
                    {{ comment.content }}
                </div>
            </li>
        {% endfor %}
    </ul>
</div>

6.使用自定义模板在详情页添加评论板块,其他页面要使用时直接使用模板标签即可

{% extends 'blog/base.html '%}
{% load comment_block %}   <!-- 导入自定义模板标签 -->
{% block main %}
	<!-- 省略其余代码 -->
	{% comment_block request.path %}
{% endblock %}

7.配置url

参考:《Django企业开发实战》

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值