Django图书荐购云平台开发与实践 - 6留言板模块

留言板模块包括读者留言和管理员回复,屏蔽或删除留言。

  1. 读者留言按时间倒序排列。
  2. 管理员回复的留言在每条读者留言的下方。
  3. 管理员可以对评论进行回复,屏蔽或删除某条留言。

首先构造留言板的模型。

#comment 模块 models.py
from django.db import models
from user.models import MyUser

class Message(models.Model):
    msgid = models.AutoField('序号', primary_key=True)
    content = models.TextField('留言内容', )
    date = models.DateField('留言时间',)
    from_user = models.ForeignKey(MyUser, on_delete=models.CASCADE, verbose_name='留言者')
    msg_status= models.IntegerField('留言状态', default=1)
    parent_msgid =  models.ForeignKey('self', verbose_name="回复留言", on_delete=models.CASCADE, blank=True, null=True)
    def __str__(self):
        return self.content

    class Meta:
        verbose_name = '用户留言'
        verbose_name_plural = '用户留言'

上面的字段中,msg_status用来表示是否显示用户的留言,默认为1表示显示留言,parent_msgid外键关联自身的msgid,表示是对关联的留言的回复留言。其他的字段很好理解。模型建好以后执行数据迁移,创建好数据表。
然后到项目的urls.py中开启最后一道大门
下面就是编写comment应用的URL地址信息和视图函数,以及在templates下添加message.html模板文件

# comment 下的 urls.py
from django.urls import path
from . import views

#设置URL的地址信息
urlpatterns = [
    path('message/', views.messageView, name='message'),
]
#comment 下的 views.py 
from django.shortcuts import render
from .models import Message
from user.models import Library, MyUser
from datetime import datetime
from django.core.paginator import Paginator, EmptyPage, PageNotAnInteger
from django.contrib.auth.decorators import login_required

@login_required(login_url='/user/login.html')
def messageView(request, page):
    #获取该用户所属馆的馆名和馆实例对象
    lib_name = request.user.lib_id
    library = Library.objects.get(lib_name=lib_name)
 
    #如果是POST请求,则说明用户在发表留言
    if request.method == 'POST':
        user_id = MyUser.objects.get(id=request.user.id)
        time = datetime.now()
        content = request.POST.get('content')
        Message.objects.create(content=content, date=time, from_user=user_id)
    
    #查询所在馆的留言记录倒序排列
    messages = Message.objects.select_related('from_user__lib_id').filter(from_user__lib_id__lib_id=library.lib_id).order_by('-msgid')

    #分页
    paginator = Paginator(messages, 5)
    try:
        pageInfo = paginator.page(page)
    except PageNotAnInteger:
        pageInfo = paginator.page(1)
    except EmptyPage:
        pageInfo = paginator.page(paginator.num_pages)

    return render(request, 'message.html', locals())

简单的讲解一下逻辑,接收到用户请求后,首先获取图书馆馆名和馆的实例对象,然后判断是不是POST请求,如果是则说明用户在发表留言,将留言相关信息保存到数据库,如果是GET请求,获取该用户所在图书馆的所有留言记录并且倒序排列,输出到模板文件message.html。最后看下模板文件。

{% extends "base.html" %}
{% load staticfiles %}

{# 隐藏顶部搜索框 #}
{% block search %}
{% endblock %}
{% block body %}
{{ lib_name }}-留言板
    {% for msg in pageInfo %} {% if msg.parent_msgid == NULL %}
    {{ msg.from_user }}  {{ msg.date }} 留言
  • {{ msg.content }}
  • {% else %}
    {{ msg.parent_msgid.from_user }}  {{ msg.parent_msgid.date }} 留言
  • {{ msg.parent_msgid.content }}
  • {{ msg.from_user }}  {{ msg.date }} 回复
  • {{ msg.content }}
  • {% endif %} {% endfor %}
{# 分页 #}
    {% if pageInfo.has_previous %}
  • 上一页
  • {% endif %} {% if pageInfo.has_next %}
  • 下一页
  • {% endif %}
{% csrf_token %}
{% endblock %}

实现效果如下:


image.png

然后就是做个留言板后台管理模块,在library应用里添加新的URL地址信息

    path('lib_msgadmin//', views.LibMsgAdminView, name='lib_msgadmin'),

编写留言板后台管理的视图函数LibMsgAdminView,别忘记头部导入相关模块和模型,这里只贴出了部分代码。

#登陆验证和身份验证
@login_required(login_url='/user/login.html')
@permission_required(perm='recommend.change_recommend')
#图书馆留言管理
def LibMsgAdminView(request, page):
    #获取该用户所属馆名
    lib_name = request.user.lib_id
    #获取该馆实例对象
    library = Library.objects.get(lib_name=lib_name)
    #如果是POST请求,则说明是管理员在回复用户留言
    if request.method == 'POST':
        #获取用户的实例对象
        myuser = MyUser.objects.get(id=request.user.id)
        #通过隐藏表单获取用户留言的msgid
        msgid=request.POST.get('msgid')
        #转为msg的实例对象
        msginstance = Message.objects.get(msgid=msgid)
        content = request.POST.get('content')
        time = datetime.now()

        Message.objects.create(content=content, date=time, from_user=myuser, parent_msgid=msginstance)

    #查询所在馆的留言记录倒序排列
    messages = Message.objects.select_related('from_user__lib_id').filter(from_user__lib_id__lib_id=library.lib_id).order_by('-msgid')

    #分页
    paginator = Paginator(messages, 5)
    try:
        pageInfo = paginator.page(page)
    except PageNotAnInteger:
        pageInfo = paginator.page(1)
    except EmptyPage:
        pageInfo = paginator.page(paginator.num_pages)

    return render(request, 'lib_msgadmin.html', locals())

后台管理的逻辑和前台差不多,主要差别就是回复留言的时候获取了隐藏表单中用户留言的msgid保存到数据表中的parent_id外键中。
模板文件lib_msgadmin.html如下:

{% extends "base.html" %}
{% load staticfiles %}

{# 隐藏顶部搜索框 #}
{% block search %}
{% endblock %}
{% block body %}
{{ lib_name }}-留言板管理
    {% for msg in pageInfo %} {% if msg.parent_msgid == NULL %}
    {{ msg.from_user }}  {{ msg.date }} 留言
  • {{ msg.content }}
  • {% else %}
    {{ msg.parent_msgid.from_user }}  {{ msg.parent_msgid.date }} 留言
  • {{ msg.parent_msgid.content }}
  • {{ msg.from_user }}  {{ msg.date }} 回复
  • {{ msg.content }}
  • {% endif %} {% endfor %}
{# 分页 #}
    {% if pageInfo.has_previous %}
  • 上一页
  • {% endif %} {% if pageInfo.has_next %}
  • 下一页
  • {% endif %}
{% endblock %}

回复留言


image.png

回复后的效果


image.png

留言板里的效果


image.png

如果需要对留言板有一个控制,比如能够屏蔽某些非法留言,就可以用到msg_status这个字段,数据表中默认是 1,我们把它该成非1的值就能实现屏蔽留言的功能。
首先到浏览展示的模板文件message.html中添加一个条件判断。

 {% if msg.msg_status == 1 %}

然后在留言板管理后台模板lib_msgadmin.html添加一个屏蔽留言的功能按钮

        {% if msg.msg_status == 1 %}
            
            {% else %}
            
{% endif %}

模板将浏览的msgid通过GET参数传递给视图函数处理。
视图函数中多做一个If判断,将GET获取到的msgid的msg_status设置为0或任意其他值即可实现留言的屏蔽。

 #如果通过GET获取到了msgid,说明是管理员用户要屏蔽该条留言
        if request.GET.get('msgid'):
            msgid = request.GET.get('msgid')
            #将留言状态设置为0
            Message.objects.filter(msgid=msgid).update(msg_status=0)

image.png

点击屏蔽按钮后,该条留言成为已屏蔽状态,进入留言板模板可以发现被屏蔽的留言不见了。


image.png

但是,我们发现留言被屏蔽了2条,现在第一页只有3条留言了,被屏蔽的留言虽然没有显示,但还是被从数据库中读取出来了,这种情况,我们只要在查询数据的时候再加 msg_status=1 这个条件,这样读取的就全是正常状态的留言了。

#comment 的 views.py
messages = Message.objects.select_related('from_user__lib_id').filter(from_user__lib_id__lib_id=library.lib_id,msg_status=1).order_by('-msgid')

现在再看留言板,第一页就是完整的5条留言了。


image.png

你可能感兴趣的:(Django图书荐购云平台开发与实践 - 6留言板模块)