DC's blog DC's blog
首页
  • 计算机基础
  • linux基础
  • mysql
  • git
  • 数据结构与算法
  • axure
  • english
  • docker
  • opp
  • oop
  • 网络并发编程
  • 不基础的py基础
  • 设计模式
  • html
  • css
  • javascript
  • jquery
  • UI
  • 第一次学vue
  • 第二次学vue
  • Django
  • drf
  • drf_re
  • 温故知新
  • flask
  • 前后端不分离

    • BBS
    • 订单系统
    • CRM
  • 前后端部分分离

    • pear-admin-flask
    • pear-admin-django
  • 前后端分离

    • 供应链系统
  • 理论基础
  • py数据分析包
  • 机器学习
  • 深度学习
  • 华中科大的网课
  • cursor
  • deepseek
  • 杂文
  • 罗老师语录
  • 关于我

    • me
  • 分类
  • 归档
GitHub (opens new window)

DC

愿我一生欢喜,不为世俗所及.
首页
  • 计算机基础
  • linux基础
  • mysql
  • git
  • 数据结构与算法
  • axure
  • english
  • docker
  • opp
  • oop
  • 网络并发编程
  • 不基础的py基础
  • 设计模式
  • html
  • css
  • javascript
  • jquery
  • UI
  • 第一次学vue
  • 第二次学vue
  • Django
  • drf
  • drf_re
  • 温故知新
  • flask
  • 前后端不分离

    • BBS
    • 订单系统
    • CRM
  • 前后端部分分离

    • pear-admin-flask
    • pear-admin-django
  • 前后端分离

    • 供应链系统
  • 理论基础
  • py数据分析包
  • 机器学习
  • 深度学习
  • 华中科大的网课
  • cursor
  • deepseek
  • 杂文
  • 罗老师语录
  • 关于我

    • me
  • 分类
  • 归档
GitHub (opens new window)
  • BBS

    • 登陆注册
    • 个人站点
    • 博客
    • 评论
      • 根评论功能实现
      • 评论楼展示
      • 子评论功能实现
      • 后台添加文章
  • 订单平台

  • CRM

  • flask+layui

  • django+layui

  • 供应链

  • 实战
  • BBS
DC
2023-12-01
目录

评论

# 根评论功能实现

urls.py

from django.conf.urls import url
from django.contrib import admin
from django.views.static import serve

from BBS import settings
from app01 import views

urlpatterns = [
    url(r'^admin/', admin.site.urls),
    url(r'^register/', views.register),  # -- 注册
    url(r'^login/', views.login),        # -- 登陆
    url(r'^get_code/', views.get_code),  # -- 获取验证码
    url(r'^home/', views.home),          # -- 首页
    url(r'^logout/', views.logout),      # -- 退出登陆
    url(r'^set_pwd/', views.set_pwd),    # -- 修改密码

    # -- 点赞点踩功能
    url(r'^up_or_down/$', views.up_or_down),
  
    # -- 文章评论功能
    url(r'^comment/$', views.comment),

    # -- 个人站点 (有名分组)
    url(r'^(?P<username>\w+)/$', views.site),

    # -- 个人站点侧边栏筛选功能!
    url(r'^(?P<username>\w+)/(?P<condition>tag|category|archive)/(?P<param>.*)', views.site),

    # -- 开放对外访问的接口
    url(r'^media/(?P<path>.*)', serve, {'document_root': settings.MEDIA_ROOT}),

    # -- 文章详情页
    url(r'^(?P<username>\w+)/article/(?P<article_id>\d+)', views.article_detail),
]
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34

views.py

from django.shortcuts import render, HttpResponse, redirect
from django.http import JsonResponse
from app01 import models
from django.db.models import Count, F
from django.db.models.functions import TruncMonth
from django.db import transaction

import json
import hashlib
import random
from PIL import Image, ImageDraw, ImageFont
from io import BytesIO, StringIO


def register(request):...


def get_random():...


def get_code(request):...


def login(request):...


def home(request):...


def logout(request):...


def set_pwd(request):...


def site(request, username, **kwargs):...


def article_detail(request, username, article_id):...


def up_or_down(request):...
  

def comment(request):
    if request.method == "POST":
        back_dic = {'code': 200, 'msg': ''}
        article_id = request.POST.get('article_id')
        content = request.POST.get('content')

        # -- 验证用户是否登陆!
        if not request.session.get('username'):
            back_dic['code'] = 1018
            back_dic['msg'] = "<a href='/login/' style='color: goldenrod'>请先登陆.</a>"
            return JsonResponse(back_dic)

        # -- 入库
        #    在这里模拟下事务的使用.
        with transaction.atomic():
            # 1.操作文章表
            article_obj = models.Article.objects.filter(pk=article_id).first()
            if not article_obj.comment_num:
                article_obj.comment_num = 1
                article_obj.save()
            else:
                article_obj.comment_num += 1
                article_obj.save()
            # 2.操作评论表
            models.Comment.objects.create(
                content=content,
                article_id=article_id,
                user_id=request.session.get('id'))
        back_dic['msg'] = '评论成功!'
        return JsonResponse(back_dic)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74

article_detail.html

{% extends 'site.html' %}

{% block content_9 %}
    <h1>{{ article_obj.title }}</h1>
    {# -- 点赞点踩样式开始 -- #}
    <div style="display: flex;justify-content: flex-end;" ...>
    {# -- 点赞点踩样式结束 -- #}

    {# -- 文章内容开始 -- #}
    <div class="article_content" ...>
    {# -- 文章内容结束 -- #}

    {# -- 评论楼开始 -- #}

    {# -- 评论楼结束 -- #}

    {# -- 评论样式开始 -- #}
    <div style="margin-top: 10px" ...>
        <p><span class="glyphicon glyphicon-envelope"></span> 发表评论</p>
        <p><textarea name="" id="comment_content" cols="30" rows="5"></textarea></p>
        <p>
            <button class="btn btn-primary submit_comment">提交评论</button>
        </p>
    </div>
    {# -- 评论样式结束 -- #}


{% endblock %}

{% block js %}
    <script>
        // 点赞点踩功能
        $('.action').click(function () {...})

        // 评论功能
        $('.submit_comment').click(function () {
            // 可以在这里面自定义属性,保存下再取
            // <button aid="{{ article_obj.pk }}">提交评论</button>
            let article_id = '{{ article_obj.pk }}'
            let content = $('#comment_content').val()
            if (!content) {
                layer.msg('请来点咖啡/评论!')
                return
            }
            // 发起ajax请求
            $.ajax({
                url: '/comment/',
                type: 'post',
                data: {
                    'article_id': article_id,
                    'content': content,
                    'csrfmiddlewaretoken': '{{ csrf_token }}',
                },
                success: function (res) {
                    if (res.code == 200) {
                        $('#comment_content').val('')
                        layer.msg(res.msg)
                    } else {
                        layer.msg(res.msg)
                    }
                }
            })
        })

    </script>
{% endblock %}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66

# 评论楼展示

在views.py的article_detail里修改添加以下代码.

def article_detail(request, username, article_id):
    # -- 验证站点是否存在、文章是否存在 但凡有一个不存在,跳转404页面
		# ... ...

    # -- 左侧筛选功能的数据还是得再传一遍
		# ... ...

    # -- 查出所有的评论
    comment_list = models.Comment.objects.filter(article__pk=article_id).all()

    return render(request, 'article_detail.html', locals())
1
2
3
4
5
6
7
8
9
10
11

在article_detail.html里添加修改以下代码!

{# -- 评论楼开始 -- #}
<div style="margin-top: 10px">
    <ul class="list-group">
        {% for comment in comment_list %}
            <li class="list-group-item">
                <p>
                    <span># {{ forloop.counter }}楼  </span>
                    <span>{{ comment.create_time|date:'Y-m-d H:i' }}</span>
                    <span>{{ comment.user.username }}</span>
                    <span class="pull-right"><a href="" class="reply">回复</a></span>
                </p>
                <p>{{ comment.content }}</p>
            </li>
        {% endfor %}
    </ul>
</div>
<div class="temp_comment"></div> {# 放临时评论的地方 #}
{# -- 评论楼结束 -- #}



$('.submit_comment').click(function () {
            // 可以在这里面自定义属性,保存下再取
            // <button aid="{{ article_obj.pk }}">提交评论</button>
            let article_id = '{{ article_obj.pk }}'
            let content = $('#comment_content').val()
            if (!content) {
                layer.msg('请来点咖啡/评论!')
                return
            }
            // 发起ajax请求
            $.ajax({
                url: '/comment/',
                type: 'post',
                data: {
                    'article_id': article_id,
                    'content': content,
                    'csrfmiddlewaretoken': '{{ csrf_token }}',
                },
                success: function (res) {
                    if (res.code == 200) {
                        $('#comment_content').val('')
                        let username = '{{ request.session.username }}'
                        let html = `
                            <li class="list-group-item">
                                <p>
                                    <span>${username}的评论:</span>
                                </p>
                                <p>${content}</p>
                            </li>
                        `
                        $('.temp_comment').append(html)
                        layer.msg(res.msg)
                    } else {
                        layer.msg(res.msg)
                    }
                }
            })
        })
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59

# 子评论功能实现

代码太杂了,不想粘贴了.. 阐述下逻辑..
点击回复按钮,可以拿到当前评论的id,此id作为点击提交评论按钮时发生的ajax请求中的parent_id数据!!
在后台添加的评论数据就具备了parent_id,而不是Null..
注意一点的是,回复按钮点击事件里的变量,评论按钮的点击事件里也要用的话,将该变量设计为全局变量即可..

我麻了.. 真心不喜欢前端. ╮( ̄▽ ̄"")╭ 前端的展示惨不忍睹.. 略.


# 后台添加文章

先创建一个应用: startapp app02 并注册应用
在admin目录下创建分路由urls.py,在总路由里做路由分发! url(r'^app02/', include('app02.urls')),

app02/urls.py

from django.conf.urls import url
from app02 import views

urlpatterns = [
    url(r'^add_article/', views.add_article),
    url(r'^article_list/', views.article_list),
]
1
2
3
4
5
6
7

app02/views.py
应该将输入的content内容进行过滤,过滤掉script标签,防止xss攻击!!! 
使用正则可以,使用 bs4模块 更容易!!略.

from django.shortcuts import render, redirect, HttpResponse
from app01 import models


def add_article(request):
    if request.method == "POST":
        title = request.POST.get('title')
        content = request.POST.get('content')
        cate = request.POST.get('cate')
        tag_list = request.POST.getlist('tag')  # -- 接收多个
        desc = content[0:100]
        # -- 这里完善点,还需要分类的id和站点id,略.
        article_obj = models.Article.objects.create(
            title=title,
            desc=desc,
            content=content,
        )
        # -- 手动给第三张表添加数据,因为用不了add、set等方法
        article_obj_list = []
        # 批量添加.
        # 当然可以一个个的添加
        # models.Article2Tag.objects.create(article=article_obj, tag_id=i)
        # models.Article2Tag.objects.create(article_id=article_obj.pk, tag_id=i)
        for i in tag_list:
            obj = models.Article2Tag(article=article_obj, tag_id=i)
            article_obj_list.append(obj)
        models.Article2Tag.objects.bulk_create(article_obj_list)
        return redirect('/app02/article_list/')

    # -- 用username=request.session.get('username')来筛选也行,但用主键更快.
    userinfo = models.UserInfo.objects.filter(pk=request.session.get('id')).first()
    # -- 必须得登陆
    if not userinfo:
        return render(request, 'error.html')
    cate_list = models.Category.objects.filter(site__pk=userinfo.site.pk).all()
    tag_list = models.Tag.objects.filter(site__pk=userinfo.site.pk).all()
    return render(request, "admin/add_article.html", locals())


def article_list(request):
    return HttpResponse('list')
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41

template/admin/add_article.html
添加内容那里可以使用富文本编辑框: kindeditor、百度富文本
去官网下载安装包,阅读使用文档进行相关的配置!

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <link href="https://cdn.bootcdn.net/ajax/libs/twitter-bootstrap/3.4.1/css/bootstrap.min.css" rel="stylesheet">
    <script src="https://cdn.bootcdn.net/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
    <script src="https://cdn.bootcdn.net/ajax/libs/twitter-bootstrap/3.4.1/js/bootstrap.min.js"></script>
    {% load static %}
    <script src="{% static 'layer-v3.5.1/layer/layer.js' %}"></script>
    <title>Title</title>
</head>
<body>
<div class="container">
    <div class="row">
        <div class="col-md-4">
            <h2 class="text-center">添加文章</h2>
            <form action="" method="post">
                {% csrf_token %}
                <p>标题: <input type="text" name="title" class="form-control"></p>
                <p>内容: <textarea name="content" id="" cols="30" rows="10"></textarea></p>
                <p>分类:
                    {% for cate in cate_list %}
                        {# 若不写value属性的值 选择后发送到后端的都是on,就不知道选的是哪个 #}
                        <input type="radio" name="cate" value="{{ cate.pk }}">{{ cate.name }}
                    {% endfor %}
                </p>
                <p>标签:
                    {% for tag in tag_list %}
                        {# 若不写value属性的值 选择后发送到后端的都是on,就不知道选的是哪个 #}
                        <input type="checkbox" name="tag" value="{{ tag.pk }}">{{ tag.name }}
                    {% endfor %}
                </p>
                <input type="submit" class="btn btn-success" value="发表">
            </form>
        </div>
    </div>
</div>
</body>
</html>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39

博客
单点知识

← 博客 单点知识→

最近更新
01
deepseek本地部署+知识库
02-17
02
实操-微信小程序
02-14
03
教学-cursor深度探讨
02-13
更多文章>
Theme by Vdoing | Copyright © 2023-2025 DC | One Piece
  • 跟随系统
  • 浅色模式
  • 深色模式
  • 阅读模式