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

模板继承即渲染:
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>
posted @ 2022-08-19 17:28  角角边  Views(32)  Comments(0)    收藏  举报