首页 > 其他分享 >10 继承模板 & inclution_tag & 文章的详情页设计 & 文章点赞 & 文章的评论

10 继承模板 & inclution_tag & 文章的详情页设计 & 文章点赞 & 文章的评论

时间:2022-08-19 17:33:28浏览次数:60  
标签:comment 10 obj content 详情页 user 文章 article id

模板继承即渲染:
image


文章点赞或反对:
image


跟评论和子评论:
image

settings.py

settings.py
USE_TZ = False  # 转时区改为False

编写url:

urls.py
from django.urls import re_path


urlpatterns = [
    ...
    path('comment/', views.comment),  # 评论
    # 文章点赞和反对
    path('digg/', views.digg),
    # 文章详情页展示
    re_path('^(?P<username>\w+)/articles/(?P<articles_id>\d+)$', views.article_detail),
]

编写视图:

views.py
import json

from django.shortcuts import render
from django.http import JsonResponse
from django.db.models import F
from blog import models

def article_detail(request, username, articles_id):
    article_obj = models.Article.objects.filter(pk=articles_id).first()
    comment_list = models.Comment.objects.filter(article_id=articles_id)

    return render(request, "article_detail.html", locals())


def digg(request):
    article_id = request.POST.get('article_id')
    is_up = json.loads(request.POST.get('is_up'))
    user_id = request.user.pk

    # 过滤重复点赞
    obj = models.ArticleUpDown.objects.filter(user_id=user_id, article_id=article_id).first()
    response = {"static": True}
    if not obj:
        ard = models.ArticleUpDown.objects.create(user_id=user_id, article_id=article_id, is_up=is_up)

        queryset = models.Article.objects.filter(pk=article_id)
        if is_up:  # 文章点赞数的数据同步
            queryset.update(up_count=F("up_count")+1)
        else:
            queryset.update(down_count=F("down_count")+1)
    else:
        response['static'] = False
        response['handled'] = obj.is_up

    return JsonResponse(response)


def comment(request):
    article_id = request.POST.get('article_id')
    pid = request.POST.get('pid')
    content = request.POST.get('content')
    user_id = request.user.pk

    comment_obj = models.Comment.objects.create(user_id=user_id, article_id=article_id, content=content, parent_comment_id=pid)

    response = {}
    response["create_time"] = comment_obj.create_time.strftime("%Y-%m-%d %X")
    response["username"] = request.user.username
    response["content"] = content

    return JsonResponse(response)

编写模板,并继承模板:

base.html
{% extends 'base.html' %}
{% load static %}
{% load my_tags %}

{% block css %}
    <style>
        #div_digg {
            float: right;
            margin-bottom: 10px;
            margin-right: 30px;
            font-size: 12px;
            width: 125px;
            text-align: center;
            margin-top: 10px;
        }

        .diggit {
            float: left;
            width: 46px;
            height: 52px;
            background: url({% static 'blog/font/upup.gif' %}) no-repeat;
            text-align: center;
            cursor: pointer;
            margin-top: 2px;
            padding-top: 5px;
        }

        .buryit {
            float: right;
            margin-left: 20px;
            width: 46px;
            height: 52px;
            background: url({% static 'blog/font/downdown.gif' %}) no-repeat;
            text-align: center;
            cursor: pointer;
            margin-top: 2px;
            padding-top: 5px;
        }

        .clear {
            clear: both;
        }

        input.author {
            background-image: url({% static 'blog/font/icon_form.gif' %});
            background-repeat: no-repeat;
            border: 1px solid #ccc;
            padding: 4px 4px 4px 30px;
            width: 300px;
            font-size: 13px;
            background-position: 3px -3px;
        }
    </style>
{% endblock %}

{% block content %}
    {% csrf_token %}

    <h3 class="text-center">{{ article_obj.title }}</h3>
    <div>
        {{ article_obj.content|safe }} <!-- safe转义 -->
    </div>

    <div class="clearfix">
        <div id="div_digg">
            <div class="diggit action" onclick="votePost(16598898,'Digg')">
                <span class="diggnum" id="digg_count">{{ article_obj.up_count }}</span>
            </div>
            <div class="buryit action" onclick="votePost(16598898,'Bury')">
                <span class="burynum" id="bury_count">{{ article_obj.down_count }}</span>
            </div>
            <div class="clear"></div>
            <div class="diggword" id="digg_tips" style="color: red"></div>
        </div>
    </div>

    <div>
        <p>评论列表</p>
        <ul class="comment_list list-group">
            {% for comment in comment_list %}
                <li class="list-group-item">
                    <div>
                        <a href=""># {{ forloop.counter }} 楼</a>&nbsp;&nbsp;
                        <span>{{ comment.create_time|date:"Y-m-d H:i" }}</span>&nbsp;&nbsp;
                        <a href=""><span>{{ comment.user.username }}</span></a>
                        <a href="" class="pull-right reply_btn" username="{{ comment.user.username }}" comment_pk="{{ comment.pk }}">回复</a>
                    </div>

                    {% if comment.parent_comment_id %}
                        <div class="pid_info well">
                            <p>{{ comment.parent_comment.user.username }}: {{ comment.parent_comment.content }}</p>
                        </div>
                    {% endif %}

                    <div style="margin-top: 10px">
                        <p>{{ comment.content }}</p>
                    </div>
                </li>
            {% endfor %}
        </ul>
        <p>发表评论</p>
        <p>昵称:<input type="text" id="tbCommentAuthor" class="author" disabled="disabled" size="50"
                     value="{{ request.user.username }}"></p>
        <p>评论内容:</p>
        <textarea id="comment_content" cols="60" rows="7"></textarea>
        <p>
            <button class="btn btn-default comment_btn">提交评论</button>
        </p>
    </div>

{% endblock %}

{% block js %}
    <script>
        // 点赞请求
        $("#div_digg .action").click(function () {
            var is_up = $(this).hasClass("diggit");
            var $obj = $(this).children("span");

            $.ajax({
                url: '/digg/',
                type: 'post',
                data: {
                    "csrfmiddlewaretoken": $('[name="csrfmiddlewaretoken"]').val(),
                    "is_up": is_up,
                    "article_id": "{{ article_obj.pk }}",
                },
                success: function (res) {
                    console.log(res);
                    if (res.static) {
                        var val = parseInt($obj.text());
                        $obj.text(val + 1);
                    } else {
                        var val = res.handled ? "您已经推荐过!" : "您已经反对过!";
                        $('#digg_tips').html(val);
                        setTimeout(function () {
                            $('#digg_tips').html("")
                        }, 1500)
                    }
                }
            })
        });

        // 评论请求
        var pid = "";
        $('.comment_btn').click(function () {
            var content = $('#comment_content').val();

            if (pid){
                var index = content.indexOf("\n");
                content = content.slice(index+1)
            }

            $.ajax({
                url: '/comment/',
                type: 'post',
                data: {
                    "csrfmiddlewaretoken": $('[name="csrfmiddlewaretoken"]').val(),
                    "article_id": "{{ article_obj.pk }}",
                    "content": content,
                    "pid": pid,
                },
                success: function (res) {
                    console.log(res)
                    var create_time = res.create_time
                    var username = res.username
                    var content = res.content

                    var s = `
                        <li class="list-group-item">
                            <div>
                                <span>${create_time}</span>&nbsp;&nbsp;
                                <a href=""><span>${username}</span></a>
                            </div>
                            <div style="margin-top: 10px">
                                <p>${content}</p>
                            </div>
                        </li>
                    `;
                    $('ul.comment_list').append(s);

                    // 清空评论框
                    $('#comment_content').val("");
                    // 清空pid
                    pid = ""
                }
            })
        });
        
        // 回复按钮事件
        $('.reply_btn').click(function () {
            var val = "@"+$(this).attr("username")+'\n';
            $('#comment_content').focus().text(val)
            pid = $(this).attr("comment_pk");
        });
    </script>
{% endblock %}


编写inclusion_tag:

my_tags.py
from django import template
from django.db.models import Count
from blog import models

register = template.Library()


@register.inclusion_tag("classification.html")
def get_classification_style(username):
    user_obj = models.UserInfo.objects.filter(username=username).first()
    blog_obj = user_obj.blog
    cate_list = models.Category.objects.filter(blog=blog_obj).values("pk").annotate(c=Count("article__title")).values_list("title", "c")
    tag_list = models.Tag.objects.filter(blog=blog_obj).values("pk").annotate(c=Count("article")).values_list("title", "c")
    date_list = models.Article.objects.filter(user=user_obj).extra(select={'y_m_date': 'date_format(create_time, "%%Y-%%m")'}).values("y_m_date").annotate(c=Count('nid')).values_list("y_m_date", "c")

    return {"username": username, "user_obj": user_obj, "blog_obj": blog_obj, "cate_list": cate_list, "tag_list": tag_list, "date_list": date_list}
    # 当代码执行完后,数据返回给classification.html模板进行渲染
classification.html
<div>
    <div class="panel panel-warning">
        <div class="panel-heading">我的标签</div>
        <div class="panel-body">
            {% for tag in tag_list %}
                <p><a href="/{{ username }}/tag/{{ tag.0 }}">{{ tag.0 }} ({{ tag.1 }})</a></p>
            {% endfor %}
        </div>
    </div>
    <div class="panel panel-danger">
        <div class="panel-heading">随笔分类</div>
        <div class="panel-body">
            {% for cate in cate_list %}
                <p><a href="/{{ username }}/category/{{ cate.0 }}">{{ cate.0 }} ({{ cate.1 }})</a></p>
            {% endfor %}

        </div>
    </div>
    <div class="panel panel-success">
        <div class="panel-heading">随笔归档</div>
        <div class="panel-body">
            {% for date in  date_list %}
                <p><a href="/{{ username }}/archive/{{ date.0 }}">{{ date.0 }} ({{ date.1 }})</a></p>
            {% endfor %}

        </div>
    </div>

</div>

标签:comment,10,obj,content,详情页,user,文章,article,id
From: https://www.cnblogs.com/it-lkp/p/16599299.html

相关文章

  • mysql运行sql文件报错[ERR] 2006 - MySQL server has gone away [ERR] -- MySQL dump
    原因:在运行数据库脚本文件时报该错,由于mysql对max_allowed_packect 允许最大的数据包的大小有限制解决方法:1.先查看现在允许的最大包大小,单位(字节) select@@max_allow......
  • GBJ1010-ASEMI整流桥GBJ1010
    编辑:llGBJ1010-ASEMI整流桥GBJ1010型号:GBJ1010品牌:ASEMI封装:GBJ-4特性:整流扁桥正向电流:10A反向耐压:1000V恢复时间:ns引脚数量:4芯片个数:4芯片尺寸:102MIL浪涌电流......
  • CF1092E. Minimal Diameter Forest
    \(\texttt{Difficulty:2000}\)题意给定\(n(1\len\le1000)\)个点,\(m(0\lem\len-1)\)条边组成的森林,现在增加一些边,是森林成为一棵树,并且其直径最小,求最小直径以及......
  • 练习10:打乱一个数组
    这种解法有问题!![12,4,16,3].sort(function(){return5-Math.random();});v8在处理sort方法时,使用了插入排序和快排两种方案。当目标数组长度小于10时,使用......
  • 一些值得阅读的前端文章(不定期更新)
    1、面向Lighthouse编程与Vue性能优化:https://mp.weixin.qq.com/s/12Xppi2LCXddRWy9Mjw43Q 2、详解HTTPS:https://mp.weixin.qq.com/s/mpoDKIsQbNdpuBNhnvvf-g 3、Web......
  • 复现CVE-2022-10270(向日葵远程代码执行漏洞)
    警告请勿使用本文提到的内容违反法律。本文不提供任何担保。漏洞描述    向日葵是一款免费的,集远程控制电脑手机、远程桌面连接、远程开机、远程管理、支持内网......
  • python菜鸟学习: 10. 函数的基本用法
    #-*-coding:utf-8-*-#回参函数deftest01():return0#以元组返回参数deftest02():return1,[1,2,3,4,5],{"name":"liyuzhoupan"}#有参函数deftest......
  • 1021 ObstacleCourse障碍训练课 优先队列+bfs+转弯
    链接:https://ac.nowcoder.com/acm/contest/26077/1021来源:牛客网题目描述考虑一个NxN(1<=N<=100)的有1个个方格组成的正方形牧场。......
  • 桐柏邀请赛 S10 题解
    EnchantedLove记\(S=a_1+a_2+\cdots+a_n\),那么:若\(S\)为偶数,则答案为\(\frac{S}{2}\)。否则,我们找到\(a\)中最小的奇数(显然此时\(a\)中必然有至少一个奇数),设......
  • Win10桌面图标显示问题
    原文链接Windows桌面图标出现模糊、阴影等显示问题。解决办法1.在桌面上鼠标右键→个性化→主题→桌面图标设置→把计算机回收站用户的文件控制面板网络等全部不选......