10 News Carousel Figure

News Carousel drawing function

analysis

  • Request Method: GET
  • url definition:/news/banners/
  • Request parameters: the front without having to pass parameters

Returned to the front end

  • Returned to the front end of a data format json format, returns the following examples
{
    'errmsg':'',
    'data':{
        'banners': [
            {
                'image_url':'/media/jichujiaochen.jpeg',
                'news_id':221,
                'news_title':'Python算法快速排序'
            },
            {
                'image_url':'/media/python_advanced.jpg',
                'news_id':707,
                'news_title':'python序列于映射的解包操作'
            }
        ]
    },
    'errno':'0'
}

The back-end code implementation

apps/news/views.py

import logging

from django.shortcuts import render
from django.views import View
from django.core.paginator import Paginator,EmptyPage   #不存在的页码报错
from django.http import Http404

from apps.news import models
from apps.news import constants

from utils.json_fun import to_json_data
from utils.res_code import Code,error_map
logger = logging.getLogger('django')

# def index(request):
#     return render(request,'news/index.html')


class IndexView(View):
    """
    constants
    """
    def get(self,request):
        # tags = models.Tag.objects.filter(is_delete=False)
        #通过表中的is_delete判断是否被删除
        tags = models.Tag.objects.only('id','name').filter(is_delete=False) #only确定要查询的字段,其他的不查
        #使用select_related关联表优化,一对一和一对多都可用,查询集,用切片获取对象
        hot_news = models.HotNews.objects.select_related('news').only('news__title','news__image_url',\
          'news_id').filter(is_delete=False).order_by('priority','-news__clicks')[0:constants.SHOW_HOTNEWS_COUNT]

        # context = {
        #     'tags':tags,
        # }
        #用模板上下文     将当前方法下的变量都传进locals,python内置函数
        # return render(request,'news/index.html',context=context)
        return render(request,'news/index.html',locals())

#ajax请求
#传参 tag_id  page
#后台的返回  图片,标题,摘要,作者,标签,更新时间,文章id
#请求方式:GET
#/news/
#url查询字符串   ?tag_id=1&page=2    /news/?tag_id=1&page=2


class NewsListView(View):
    """
    对于一对一字段(OneToOneField)和外键字段(ForeignKey),可以使用select_related 来对QuerySet进行优化。
    select_related 返回一个QuerySet,当执行它的查询时它沿着外键关系查询关联的对象的数据。
    它会生成一个复杂的查询并引起性能的损耗,但是在以后使用外键关系时将不需要数据库查询
    """

    def get(self,request):
        """
        # 1.获取参数
        # 2.校验参数
        # 3.从数据库拿数据
        # 4.分页
        # 5.序列化输出
        #6.返回给前端
        :param request:
        :return:
        """
        #1.获取参数,校验参数
        #如果通过不正当手段导致int转换不成功时,返回最新资讯给前端
        try:
            # 如果没传或者格式不对得不到数据,为0,则把最新资讯id设置为0,当刚进入首页没进行选择标签时起作用,即默认为最新资讯
            tag_id = int(request.GET.get('tag_id',0))   #get到的是str类型,存入数据库是int类型
        except Exception as e:
            logger.error('标签错误:\n{}'.format(e))
            tag_id = 0
        try:
            page = int(request.GET.get('page',1))
        except Exception as e:
            logger.error('页码错误:\n{}'.format(e))
            page = 1
        #3.从数据库中拿数据
        #title,digest(摘要),image_url,update_time
        #select_related用于多表查询,是优化措施,参数是关联外键的字段,id为主键,无论怎样都会查到,所以不需要列出来
        #News中的tag字段对应Tag标签中的name字段,News中的author字段对应Users中的username字段
        news_queryset = models.News.objects.select_related('tag','author').only('title','digest',\
                        'image_url','update_time','tag__name','author__username')
        #is_delete:是否被逻辑删除,tag_id=0在queryset中表示为空
        news = news_queryset.filter(is_delete=False,tag_id=tag_id) or news_queryset.filter(is_delete=False)
        #4.分页
        paginator = Paginator(news,constants.PER_PAGE_NEWS_COUNT)   #第一个参数是数据,第二个参数是每页的新闻个数
        try:
            news_info = paginator.page(page)    #对应页的新闻
        except EmptyPage:
            logger.error('用户访问页数大于总页数')
            news_info = paginator.page(paginator.num_pages) #展示最大页码的新闻
        #5.序列化输出
        news_info_list = []
        for n in news_info:
            news_info_list.append({
                'id':n.id,
                'title':n.title,
                'digest':n.digest,
                'image_url':n.image_url,
                'update_time':n.update_time.strftime('%Y-%m-%d %H:%M:%S'),
                'tag_name':n.tag.name,  #tag的name属性
                'author':n.author.username,
            })
        data = {    #返回给前端的,名一定要和前端对应否则没作用,细心
            'news':news_info_list,
            'total_pages':paginator.num_pages    #总页码数
        }
        #6.返回给前端
        return to_json_data(data=data)


class NewsBanner(View):
    """
    ajax
    """
    #不传参,不改数据,用get
    def get(self,request):
        banners = models.Banner.objects.select_related('news').only('image_url','news_id','news__title').\
            filter(is_delete=False).order_by('priority')[0:constants.SHOW_BANNER_COUNT]
        #序列化输出
        banners_info_list = []
        for b in banners:
            banners_info_list.append(
                {
                    'image_url':b.image_url,
                    'news_id':b.news_id,
                    'news_title':b.news.title
                }
            )
        data = {
            'banners':banners_info_list,
        }
        return to_json_data(data=data)  #返回给前端

#文章详情
#参数:news_id
#title author__username update_time tag_names content

class NewsDetailView(View):
    """
    /news/<int:news_id>/
    将文章id携带到url
    """
    def get(self,request,news_id):
        news = models.News.objects.select_related('tag','author').only('title','content','update_time',\
                   'tag__name','author__username').filter(is_delete=False,id=news_id).first()
        if news:
            return render(request,'news/news_detail.html',locals())
        else:
            raise Http404('新闻id不存在'.format(news_id))

apps/news/constants.py

#每页新闻数
PER_PAGE_NEWS_COUNT = 5
#显示热门新闻条数
SHOW_HOTNEWS_COUNT = 3
#轮播图每页新闻数
SHOW_BANNER_COUNT = 6

apps/news/urls.py

from django.urls import path, re_path


from apps.news import views

app_name = 'news'

urlpatterns = [
    # path('',views.index,name='index'),
    path('',views.IndexView.as_view(),name='index'),
    path('news/',views.NewsListView.as_view(),name='news_list'),
    path('news/banners/',views.NewsBanner.as_view(),name='news_banner'),
    path('news/<int:news_id>/',views.NewsDetailView.as_view(),name='news_detail')
]
  • Backstage pass front-end: context, ajax
  • Backstage pass the front: form form

Here Insert Picture Description

Front-end code implementation

templates/news/index.html

{% extends 'base/base.html' %}
{% load static %}
{% block title %}<title>IndexPage</title>{% endblock %}
{% block link %}
  <link rel="stylesheet" href="{% static 'css/news/index.css' %}">
{% endblock %}

  <!-- main-contain start  -->
{% block contain %}
  <div class="main-contain">
    <!-- banner start -->
      <div class="banner">
          <ul class="pic">
              <!--淡入淡出banner-->
{#              <li><a href="javascript:void(0);"><img src="{% static 'img/ui.png' %}" alt="test"></a></li>#}
{#              <li><a href="javascript:void(0);"><img src="{% static 'img/youxi.png' %}" alt="test"></a></li>#}
{#              <li><a href="javascript:void(0);"><img src="{% static 'img/dianshang.png' %}" alt="test"></a></li>#}
{##}
{##}
{#              <li><a href="javascript:void(0);"><img src="{% static 'img/zimeiti.png' %}" alt="test"></a></li>#}
{##}
{##}
{#              <li><a href="javascript:void(0);"><img src="{% static 'img/python_gui.jpg' %}" alt="test"></a></li>#}
{##}
{##}
{#              <li><a href="javascript:void(0);"><img src="{% static 'img/linux.jpg' %}" alt="test"></a></li>#}


          </ul>
          <a href="javascript:void(0);" class="btn prev">
              <i class="PyWhich py-arrow-left"></i></a>
          <a href="javascript:void(0);" class="btn next">
              <i class="PyWhich py-arrow-right"></i></a>
          <ul class="tab">
              <!-- 按钮数量必须和图片一致 -->


{#              <li></li>#}
{##}
{##}
{#              <li></li>#}
{##}
{##}
{#              <li></li>#}
{##}
{##}
{#              <li></li>#}
{##}
{##}
{#              <li></li>#}
{##}
{##}
{#              <li></li>#}


          </ul>
      </div>
    <!-- banner end -->

    <!-- content start -->
    <div class="content">
      <!-- recommend-news start -->
        <ul class="recommend-news">
          {% for n in hot_news %}
            <li>
              <a href="{% url 'news:news_detail' n.news.id %}" target="_blank">
                <div class="recommend-thumbnail">
                  <img src="{{ n.news.image_url }}" alt="title">
                </div>
                <p class="info">{{ n.news.title }}</p>
              </a>
            </li>
          {% endfor %}
{#            <li>#}
{#                <a href="https://www.shiguangkey.com/course/2432" target="_blank">#}
{#                    <div class="recommend-thumbnail">#}
{#                        <img src="{% static 'img/python_gui.jpg' %}" alt="title">#}
{#                    </div>#}
{#                    <p class="info">Python GUI 教程 25行代码写一个小闹钟</p>#}
{#                </a>#}
{#            </li>#}
{##}
{#            <li>#}
{#                <a href="https://www.shiguangkey.com/course/2432" target="_blank">#}
{#                    <div class="recommend-thumbnail">#}
{#                        <img src="{% static 'img/python_advanced.jpg' %}" alt="title">#}
{#                    </div>#}
{#                    <p class="info">python高性能编程方法一</p>#}
{#                </a>#}
{#            </li>#}
{##}
{#            <li>#}
{#                <a href="https://www.shiguangkey.com/course/2432" target="_blank">#}
{#                    <div class="recommend-thumbnail">#}
{#                        <img src="{% static 'img/jichujiaochen.jpeg' %}" alt="title">#}
{#                    </div>#}
{#                    <p class="info">python基础 split 和 join函数比较</p>#}
{#                </a>#}
{#            </li>#}
        </ul>
      <!-- recommend-news end -->

      <!--  news-nav start-->
        <nav class="news-nav">
            <ul class="clearfix">
                <li class="active"><a href="javascript:void(0)" data-id="0">最新资讯</a></li>
                {% for tag in tags %}
                <li><a href="javascript:void(0)" data-id="{{ tag.id }}">{{ tag.name }}</a></li>
                {% endfor %}
{#                <li><a href="javascript:void(0)" data-id="2">Python基础</a>#}
{#                </li>#}
{##}
{#                <li><a href="javascript:void(0)" data-id="3">Python高级</a>#}
{#                </li>#}
{##}
{#                <li><a href="javascript:void(0)" data-id="4">Python函数</a>#}
{#                </li>#}
{##}
{#                <li><a href="javascript:void(0)" data-id="5">PythonGUI</a>#}
{#                </li>#}
{##}
{#                <li><a href="javascript:void(0)" data-id="6">Linux教程</a>#}
{#                </li>#}

            </ul>
        </nav>
      <!--  news-nav end -->

      <!-- news-contain start -->
        <div class="news-contain">
            <ul class="news-list">
{##}
{#                <li class="news-item">#}
{#                    <a href="https://www.shiguangkey.com/course/2432" class="news-thumbnail"#}
{#                       target="_blank">#}
{#                        <img src="{% static 'img/linux.jpg' %}" alt="linux查找文件或目录命令"#}
{#                             title="linux查找文件或目录命令">#}
{#                    </a>#}
{#                    <div class="news-content">#}
{#                        <h4 class="news-title"><a#}
{#                                href="#">linux查找文件或目录命令</a>#}
{#                        </h4>#}
{#                        <p class="news-details">linux查找文件或目录命令,前提:知道文件或者目录的具体名字,例如:sphinx.conffind 查找find / -name#}
{#                            dirname 查找目录find -name...</p>#}
{#                        <div class="news-other">#}
{#                            <span class="news-type">Linux教程</span>#}
{#                            <span class="news-time">11/11 18:24</span>#}
{#                            <span class="news-author">python</span>#}
{#                        </div>#}
{#                    </div>#}
{#                </li>#}
{##}
{#                <li class="news-item">#}
{#                    <a href="https://www.shiguangkey.com/course/2432" class="news-thumbnail"#}
{#                       target="_blank">#}
{#                        <img src="{% static 'img/linux.jpg' %}" alt="linux下svn命令的使用"#}
{#                             title="linux下svn命令的使用">#}
{#                    </a>#}
{#                    <div class="news-content">#}
{#                        <h4 class="news-title"><a#}
{#                                href="https://www.shiguangkey.com/course/2432/887">linux下svn命令的使用</a>#}
{#                        </h4>#}
{#                        <p class="news-details">1、将文件checkout到本地目录svn checkout path(path是服务器上的目录) 例如:svn checkout#}
{#                            svn://192.168.1.1/pro/domain 简写:svn co2、往版本库中添加新的文件 svn addfile 例如:svn add te...</p>#}
{#                        <div class="news-other">#}
{#                            <span class="news-type">Linux教程</span>#}
{#                            <span class="news-time">11/11 18:24</span>#}
{#                            <span class="news-author">python</span>#}
{#                        </div>#}
{#                    </div>#}
{#                </li>#}
{##}
{#                <li class="news-item">#}
{#                    <a href="https://www.shiguangkey.com/course/2432" class="news-thumbnail"#}
{#                       target="_blank">#}
{#                        <img src="{% static 'img/linux.jpg' %}" alt="实现linux和windows文件传输"#}
{#                             title="实现linux和windows文件传输">#}
{#                    </a>#}
{#                    <div class="news-content">#}
{#                        <h4 class="news-title"><a#}
{#                                href="https://www.shiguangkey.com/course/2432/886">实现linux和windows文件传输</a>#}
{#                        </h4>#}
{#                        <p class="news-details">#}
{#                            其实这个题目有点大,这里介绍的只是linux和windows文件传输中的一种,但是这种方法却非常实用,那就是:ZModem协议具体是linux命令是:rz...</p>#}
{#                        <div class="news-other">#}
{#                            <span class="news-type">Linux教程</span>#}
{#                            <span class="news-time">11/11 18:24</span>#}
{#                            <span class="news-author">python</span>#}
{#                        </div>#}
{#                    </div>#}
{#                </li>#}
{##}
{#                <li class="news-item">#}
{#                    <a href="https://www.shiguangkey.com/course/2432" class="news-thumbnail"#}
{#                       target="_blank">#}
{#                        <img src="{% static 'img/linux.jpg' %}" alt=".htaccess配置详解"#}
{#                             title=".htaccess配置详解">#}
{#                    </a>#}
{#                    <div class="news-content">#}
{#                        <h4 class="news-title"><a#}
{#                                href="https://www.shiguangkey.com/course/2432">.htaccess配置详解</a>#}
{#                        </h4>#}
{#                        <p class="news-details">  .htaccess文件设置基础教程 如果你设置好了比如常用的404页面 301重定向 页面还有500页面等会设置了#}
{#                            无非对你的seo技术有很大帮助那么 .htaccess文件到底怎么设置呢  - .htaccess 文件(或者&quot;分布式...</p>#}
{#                        <div class="news-other">#}
{#                            <span class="news-type">Linux教程</span>#}
{#                            <span class="news-time">11/11 18:24</span>#}
{#                            <span class="news-author">python</span>#}
{#                        </div>#}
{#                    </div>#}
{#                </li>#}
{##}
{#                <li class="news-item">#}
{#                    <a href="https://www.shiguangkey.com/course/2432" class="news-thumbnail"#}
{#                       target="_blank">#}
{#                        <img src="{% static 'img/linux.jpg' %}" alt="使用nohup命令让linux程序后台运行"#}
{#                             title="使用nohup命令让linux程序后台运行">#}
{#                    </a>#}
{#                    <div class="news-content">#}
{#                        <h4 class="news-title"><a#}
{#                                href="https://www.shiguangkey.com/course/2432">使用nohup命令让linux程序后台运行</a>#}
{#                        </h4>#}
{#                        <p class="news-details">使用nohup让程序永远后台运行Unix/Linux下一般比如想让某个程序在后台运行,很多都是使用 &amp;#}
{#                            在程序结尾来让程序自动运行。比如我们要运行mysql在后台:/usr/local/mysql/bin/mysqld_safe --user=mysql &amp;但是...</p>#}
{#                        <div class="news-other">#}
{#                            <span class="news-type">Linux教程</span>#}
{#                            <span class="news-time">11/11 18:24</span>#}
{#                            <span class="news-author">python</span>#}
{#                        </div>#}
{#                    </div>#}
{#                </li>#}

            </ul>
        </div>
      <!-- news-contain end -->

      <!-- btn-more start -->
{#      <a href="javascript:void(0);" class="btn-more">加载更多</a>#}
      <!-- btn-more end -->
    </div>
    <!-- content end -->
  </div>
{% endblock %}
    <!-- main-contain  end -->

<!-- main end -->

<!-- footer start -->

<!-- footer end -->
{% block domready %}
  <script src="{% static 'js/commons.js' %}"></script>
  <script src="{% static 'js/news/index.js' %}"></script>
{% endblock %}

static/js/news/index.js

$(function () {
  // 新闻列表功能
  let $newsLi = $(".news-nav ul li");
  let iPage = 1;  //默认第1页
  let iTotalPage = 1; //默认总页数为1
  let sCurrentTagId = 0; //默认分类标签为0
  let bIsLoadData = true;   // 是否正在向后台加载数据

  // 加载新闻列表信息
  fn_load_content();

  $newsLi.click(function () {
    // 点击分类标签,则为点击的标签加上一个class属性为active
    // 并移除其它兄弟元素上的,值为active的class属性
    $(this).addClass('active').siblings('li').removeClass('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 {
          message.showInfo('已全部加载,没有更多内容!');
          $(".btn-more").remove();  // 删除标签
          $(".news-list").append($('<a href="javascript:void(0);" class="btn-more">已全部加载,没有更多内容!</a>'))

        }
      }
    }
  });

  // 新闻轮播图功能
  fn_load_banner();
  /*=== bannerStart ===*/
  let $banner = $('.banner');
  let $picLi = $(".banner .pic li");
  let $prev = $('.banner .prev');
  let $next = $('.banner .next');
  let $tabLi = $('.banner .tab li');
  let index = 0;

  // 小原点
  $tabLi.click(function () {
    index = $(this).index();
    $(this).addClass('active').siblings('li').removeClass('active');
    $picLi.eq(index).fadeIn(1500).siblings('li').fadeOut(1500);
  });
  // 点击切换上一张
  $prev.click(function () {
    index--;
    if (index < 0) {
      index = $tabLi.length - 1
    }
    $tabLi.eq(index).addClass('active').siblings('li').removeClass('active');
    $picLi.eq(index).fadeIn(1500).siblings('li').fadeOut(1500);
  }).mousedown(function () {
    return false
  });

  $next.click(function () {
    auto();
  }).mousedown(function () {
    return false
  });
  //  图片向前滑动
  function auto() {
    index++;
    index %= $tabLi.length;
    $tabLi.eq(index).addClass('active').siblings('li').removeClass('active');
    $picLi.eq(index).fadeIn(3000).siblings('li').fadeOut(3000);
  }

  // 定时器
  let timer = setInterval(auto, 2000);
  $banner.hover(function () {
    clearInterval(timer)
  }, function () {
    auto();
  });

  /*=== bannerEnd ===*/


  // 定义向后端获取新闻列表数据的请求
  function fn_load_content() {
    // let sCurrentTagId = $('.active a').attr('data-id');

    // 创建请求参数
    let sDataParams = {
      "tag_id": sCurrentTagId,
      "page": iPage
    };

    // 创建ajax请求
    $.ajax({
      // 请求地址
      url: "/news/",  // url尾部需要添加/
      // 请求方式
      type: "GET",
      data: sDataParams,
      // 响应数据的格式(后端返回给前端的格式)
      dataType: "json",
    })
      .done(function (res) {
        if (res.errno === "0") {
          iTotalPage = res.data.total_pages;  // 后端传过来的总页数
          if (iPage === 1) {
            $(".news-list").html("")
          }

          res.data.news.forEach(function (one_news) {
            let content = `
              <li class="news-item">
                 <a href="/news/${one_news.id}/" class="news-thumbnail" target="_blank">
                    <img src="${one_news.image_url}" alt="${one_news.title}" title="${one_news.title}">
                 </a>
                 <div class="news-content">
                    <h4 class="news-title"><a href="/news/${one_news.id}">${one_news.title}</a></h4>
                    <p class="news-details">${one_news.digest}</p>
                    <div class="news-other">
                      <span class="news-type">${one_news.tag_name}</span>
                      <span class="news-time">${one_news.update_time}</span>
                      <span class="news-author">${one_news.author}</span>
                    </div>
                 </div>
              </li>`;
            $(".news-list").append(content)
          });

          $(".news-list").append($('<a href="javascript:void(0);" class="btn-more">滚动加载更多</a>'));
          // 数据加载完毕,设置正在加载数据的变量为false,表示当前没有在加载数据
          bIsLoadData = false;

        } else {
          // 登录失败,打印错误信息
          message.showError(res.errmsg);
        }
      })
      .fail(function () {
        message.showError('服务器超时,请重试!');
      });
  }

  function fn_load_banner() {
    $.ajax({
      // 请求地址
      url: "/news/banners/",  // url尾部需要添加/
      // 请求方式
      type: "GET",
      async: false
    })
      .done(function (res) {
        if (res.errno === "0") {
          let content = ``;
          let tab_content = ``;
          res.data.banners.forEach(function (one_banner, index) {
            if (index === 0){
              content = `
                <li style="display:block;"><a href="/news/${one_banner.news_id}/">
                 <img src="${one_banner.image_url}" alt="${one_banner.news_title}"></a></li>
              `;
              tab_content = `<li class="active"></li>`;
            } else {
              content = `
              <li><a href="/news/${one_banner.news_id}/"><img src="${one_banner.image_url}" alt="${one_banner.news_title}"></a></li>
              `;
              tab_content = `<li></li>`;
            }

            $(".pic").append(content);
            $(".tab").append(tab_content)
          });

        } else {
          // 登录失败,打印错误信息
          message.showError(res.errmsg);
        }
      })
      .fail(function () {
        message.showError('服务器超时,请重试!');
      });
  }

});

templates/news/news_detail.html

{% extends 'base/base.html' %}
{% load static %}
{% block meta %}
<meta name="renderer" content="webkit">
  <meta name="viewport" content="width=device-width,initial-scale=1,user-scalable=0">
{% endblock %}
  {% block title %}<title>news-detail</title>{% endblock %}
  {% block link %}<link rel="stylesheet" href="{% static 'css/news/news-detail.css' %}">{% endblock %}
  {% block contain %}
    <div class="news-contain">
      <h1 class="news-title">{{ news.title }}</h1>
      <div class="news-info">
        <div class="news-info-left">
          <span class="news-author">{{ news.author.username }}</span>
          <span class="news-pub-time">{{ news.update_time }}</span>
          <span class="news-type">{{ news.tag.name }}</span>
        </div>
      </div>
      <article class="news-content">
{#        {{ news.content}}#}
        {{ news.content|safe }}
      </article>
      <div class="comment-contain">
        <div class="comment-pub clearfix">
          <div class="new-comment">
            文章评论(<span class="comment-count">0</span>)
          </div>
          <div class="comment-control please-login-comment" style="display:none;">
            <input type="text" placeholder="请登录后参加评论">
          </div>
          <div class="comment-control logged-comment">
            <input type="text" placeholder="请填写评论">
          </div>
          <button class="comment-btn">发表评论</button>
        </div>
        <ul class="comment-list">
          <li class="comment-item">
            <div class="comment-info clearfix">
              <img src="{% static 'img/avatar.jpeg' %}" alt="avatar" class="comment-avatar">
              <span class="comment-user">评论人</span>
              <span class="comment-pub-time">1小时前</span>
            </div>
            <div class="comment-content">这是一条评论</div>
          </li>
          <li class="comment-item">
            <div class="comment-info clearfix">
              <img src="{% static 'img/avatar.jpeg' %}" alt="avatar" class="comment-avatar">
              <span class="comment-user">评论人</span>
              <span class="comment-pub-time">1小时前</span>
            </div>
            <div class="comment-content">这是一条评论</div>
          </li>
        </ul>
      </div>

    </div>
    <!-- side end -->
  {% endblock %}

Guess you like

Origin blog.csdn.net/xiaogeldx/article/details/91181577