Django blog项目《十一》:文章模块2 《文章列表、详情、评论、回复》

该博客介绍了如何在Django项目中实现文章列表的动态加载、文章详情展示以及评论和回复功能。文章列表通过urls.py配置、后端view逻辑和前端js实现动态加载;文章详情页涉及urls.py、view处理及html页面填充;评论和回复功能共享逻辑,使用相同前后端配置,并在index.html中呈现。
摘要由CSDN通过智能技术生成

文章显示列表这里采用动态加载的方法,文章回复采用二级评论的方法来实现。

一、文章列表功能

1. urls.py配置

news/urls.py

from django.urls import path
from news import views


app_name = "news"

urlpatterns = [
    path("article_list/", views.ArticleView.as_view(), name="article_list"),
]
2. 后端view逻辑处理

news/views.py

import logging

from django.views import View
from django.shortcuts import render
from django.core.paginator import Paginator, EmptyPage, PageNotAnInteger

from news import contains  # 上一章已有
from news import models as _models
from utils.res_code.json_function import to_json_data

logger = logging.getLogger("django")


class ArticleView(View):
    def get(self, request):
        # 1. 获取前端传来的数据文章类型id
        try:
            tag_id = int(request.GET.get("tag_id", 0))
        except Exception as e:
            logger.error("文章标签id参数错误:{}".format(e))
            tag_id = 0

        # 2. 获取前端传来的数据页码编号 page_num
        try:
            page_num = int(request.GET.get("page", 1))
        except Exception as e:
            logger.error("文章页码参数错误:{}".format(e))
            page_num = 1

        # 3. 从数据库中获取文章表签id为tag_id的数据
        article_queryset_total = _models.Articles.objects.select_related("author", "tag").only("id", "title", "digest",
                                                                                    "update_time",
                                                                                    "clicks","image_url",
                                                                                    "author__username",
                                                                                    "tag__name").filter(is_delete=False)

        article_tag_queryset = article_queryset_total.filter(is_delete=False, tag_id=tag_id) or \
                          article_queryset_total.filter(is_delete=False)

        # 4. 对数据尽心分页
        pagen = Paginator(article_tag_queryset,contains.PER_PAGE_DATA_NUMBER)  # 传递待分页对象 、每页多少个

        # 5. 返回当页数据
        try:
            article_list = pagen.page(page_num)
        except EmptyPage:
            logger.error("访问页数超过总页数")
            article_list = pagen.page(pagen.num_pages)

        # 6. 数据序列化
        article_per_page_list = []
        for article in article_list:
            article_per_page_list.append({
   
                "id": article.id,
                "title": article.title,
                "digest": article.digest,
                "update_time": article.update_time.strftime("%Y年%m月%d日 %H:%M"),
                "clicks": article.clicks,
                "image_url": article.image_url,
                "author": article.author.username,
                "tag_name": article.tag.name,
            })

        data = {
   
            "total_page": pagen.num_pages,
            "article": article_per_page_list
        }
        return to_json_data(data=data)


3. 前端js实现

js/news/index.js

$(function () {
   
    let iPage = 1;  // 设定默认的page页码为1
    let sCurrentTagId = 0; // 设定默认的tag_id为0
    let $newsList = $(".news-nav ul li"); //获取到标签栏
    let iTotalPage = 1;  //设定默认的总页数为1
    let bIsLoadData = true;   //是否正在向后端传递参数

    fn_load_content();   //调用向后端请求数据函数

    $newsList.click(function () {
   
        //点击分类标签,则为点击的标签加上一个class属性为active
        //冰衣橱其他兄弟元素的上的值为active的class属性
        $(this).addClass("active").siblings("li").attr("active");
        //获取绑定在当前选中分类上的data-id属性值
        let sClickTagId = $(this).children("a").attr("data-id");

        if (sClickTagId !== sCurrentTagId) {
   
            sCurrentTagId = sClickTagId; //记录当前的分类id
            iPage = 1;
            iTotalPage = 1;
            fn_load_content()
        }

    });

    // 滚动鼠标动态加载数据
    $(window).scroll(function () {
   
        // 浏览器窗口高度
        let showHeight = $(window).height();

        //整个网页的高度
        let pageHeight = $(document).height();

        //页面可以滚动的距离
        let canScrollHeight = pageHeight - showHeight;

        // 页面滚动了多少,整个是睡着页面滚动实时变化的
        let nowScroll = $(document).scrollTop();

        if ((canScrollHeight - nowScroll) < 100) {
   
            //判断页数,去更新新闻数据
            if (!bIsLoadData) {
   
                bIsLoadData = true;
                //如果当前页面数据如果小于总页数,那么才去加载数据
                if (iPage < iTotalPage) {
   
                    iPage += 1;
                    $(".btn-more").remove(); //删除标签
                    //去加载数据
                    fn_load_content()
                } else {
   
                    alert("已经全部加载,没有更多内容了!");
                    $(".btn-more").remove(); //删除标签
                    $(".news-list").append($('<a href="javascript:void(0)" class="btn-more">已全部加载 </a>'))
                }
            }

        }
    });

    // 向前端发送请求获取数据
    function fn_load_content() {
   
        //构建参数
        let sDataParams = {
   
            "page": iPage
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值