文章详情页

一、文章详情页访问设计

  访问文章详情页,访问文章路径类似:https://www.cnblogs.com/wupeiqi/articles/3148888.html

  参照访问路径编写文章详情页路由如下:

urlpatterns = [
    ...
    # 文章详情页
    re_path(‘^(?P<username>\w+)/articles/(?P<article_id>\d+)$‘, views.article_detail),
]

二、文章详情页的数据构建

  文章详情页的head部分和左侧区域应该和个人站点保持一致。因此需要用到继承extend。

1、创建并编写base.html

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <!-- 引入 Bootstrap 核心 CSS 文件 -->
    <link rel="stylesheet" href="/static/blog/bootstrap-3.3.7/css/bootstrap.css">
    <!-- jQuery (Bootstrap 的所有 JavaScript 插件都依赖 jQuery,所以必须放在前边) -->
    <script src="/static/js/jquery-3.3.1.js"></script>
    <!-- 引入 Bootstrap 核心 JavaScript 文件 -->
    <script src="/static/blog/bootstrap-3.3.7/js/bootstrap.js"></script> <!--依赖jquery-->
    <style>
        * {
            margin: 0;
            padding: 0;
        }

        .header {
            width: 100%;
            height: 60px;
            background-color: #369;
        }

        .header .title {
            font-size: 18px; /* 字体大小 */
            font-weight: 100; /* 字体粗细 */
            line-height: 60px; /* 行高与页头一致,完成居中 */
            color: white;
            margin-left: 15px;
            margin-top: -10px;
        }

        .backend {
            float: right; /* 浮动到右边 */
            color: white;
            text-decoration: none; /* 去除下划线 */
            font-size: 16px;
            margin-right: 12px;
            margin-top: 10px;
        }
        .pub_info {
            margin-top: 10px;
            color: darkgray;
        }
    </style>
</head>
<body>

<div class="header">
    <div class="content">
        <!--站点标题-->
        <p class="title">
            <span>{{ blog.title }}</span>
            <a href="" class="backend">管理</a>
        </p>
    </div>
</div>

<div class="container">
    <div class="row">
        <div class="col-md-3">
            <!--添加bootstrap面板-->
            <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>
        <div class="col-md-9">
            {% block content %}

            {% endblock %}
        </div>
    </div>
</div>

</body>
</html>

  注意:base.html保留了原先home_site.html大部分代码,将col-md-9的部分替换为如下:

<div class="col-md-9">
    {% block content %}

    {% endblock %}
</div>

  block 告诉模版引擎: 子模版可能会覆盖掉模版中的这些位置。

2、修改home_site.html继承base.html

{% extends ‘base.html‘ %}

{% block content %}
    <div class="article_list">
                <div class="article_list">
                    {% for article in article_list %}
                        <div class="article-item clearfix">
                            <h5><a href="">{{ article.title }}</a></h5>
                            <div class="article-desc">
                                {# 文章摘要 #}
                                {{ article.desc }}
                            </div>
                            <!--文章下方详细信息-->
                            <div class="small pub_info pull-right">
                                {# 文章发布时间 #}
                                <span>发布于  {{ article.create_time|date:"Y-m-d H:i" }}</span>   
                                {# 评论数 #}
                                <span class="glyphicon glyphicon-comment"></span> 评论({{ article.comment_count }})  
                                {# 点赞数 #}
                                <span class="glyphicon glyphicon-thumbs-up"></span> 点赞({{ article.up_count }})
                            </div>
                        </div>
                        <hr>
                    {% endfor %}
                </div>
            </div>
{% endblock %}

  extends 标签是这里的关键。它告诉模版引擎,这个模版“继承”了另一个模版。当模版系统处理这个模版时,首先将定位父模版——在此例中,就是“base.html”。

  模版引擎将注意到 base.html 中的 block 标签,并用子模版中的内容来替换这些block。

  

3、详情页面head部分和左侧区域数据引入

(1)方法一

  由于home_site.html和article_detail.html都需要引入如下数据:

user = UserInfo.objects.filter(username=username).first()
blog = user.blog

cate_list = models.Category.objects.filter(blog=blog).values("pk").annotate(c=Count("article__title"))    .values_list("title", "c")

tag_list = models.Tag.objects.filter(blog=blog).values("pk").annotate(c=Count("article"))    .values_list("title", "c")

date_list = models.Article.objects.filter(user=user).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")

  在views.py中定义一个新的函数get_classification_data:

def get_classification_data(username):
    user = UserInfo.objects.filter(username=username).first()
    blog = user.blog

    cate_list = models.Category.objects.filter(blog=blog).values("pk").annotate(c=Count("article__title"))         .values_list("title", "c")

    tag_list = models.Tag.objects.filter(blog=blog).values("pk").annotate(c=Count("article"))         .values_list("title", "c")

    date_list = models.Article.objects.filter(user=user).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 {"blog": blog, "cate_list": cate_list, "tag_list": tag_list, "date_list": date_list}

  依此可以改写视图函数home_site和article_detail,以article_detail为例:

def article_detail(request, username, article_id):

    context = get_classification_data(username)

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

方法二:运用inclusion_tag

  在cnblog/blog/目录下创建templatestags目录,再创建my_tags.py文件。

(1)先快速创建简单tag,简单tag:只带一个参数,返回经过处理的字符串

  Django提供了一种simple_tag方法来快速创建类似这样的tag。

from django import template

register = template.Library()

# 乘法的函数
@register.simple_tag
def multi_tag(x,y):
    return x*y

  修改article_detail.html,load用来载入一个过滤器或者tag, 在这里引入my_tags:

{% extends "base.html" %}

{% block content %}
    {% load my_tags %}

    {% multi_tag 3 9 %}
{% endblock %}

  显示效果如下所示:

  

(2)创建inclusion tag

  样式和数据结合为一个整体的时候可以考虑使用inclusion_tag.

my_tags.py:

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

register = template.Library()

# 乘法的函数
@register.simple_tag
def multi_tag(x,y):
    return x*y

@register.inclusion_tag("classification.html")
def get_classification_style(username):
    user = models.UserInfo.objects.filter(username=username).first()
    blog = user.blog

    cate_list = models.Category.objects.filter(blog=blog).values("pk").annotate(c=Count("article__title"))         .values_list("title", "c")

    tag_list = models.Tag.objects.filter(blog=blog).values("pk").annotate(c=Count("article"))         .values_list("title", "c")

    date_list = models.Article.objects.filter(user=user).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, "blog": blog, "cate_list": cate_list, "tag_list": tag_list, "date_list": date_list}

将base.html中左侧边栏的面板代码内容取出,放置于classification.html中:

base.html:

<body>
<div class="header">
    <div class="content">
        <!--站点标题-->
        <p class="title">
            <span>{{ blog.title }}</span>
            <a href="" class="backend">管理</a>
        </p>
    </div>
</div>

<div class="container">
    <div class="row">
        <div class="col-md-3">
            <!--添加bootstrap面板-->
            {% load my_tags %}
            {% get_classification_style username %}  
        </div>
        <div class="col-md-9">
            {% block content %}

            {% endblock %}
        </div>
    </div>
</div>

</body>

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>

  修改article_detail视图函数:

def article_detail(request, username, article_id):

    # context = get_classification_data(username)
    # return render(request, "article_detail.html", context)

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

三、文章详情页渲染的标签字符串转义

  Django的模板中会对HTML标签和JS等语法标签进行自动转义,原因显而易见,这样是为了安全。但是有的时候我们可能不希望这些HTML元素被转义,比如我们做一个内容管理系统,后台添加的文章中是经过修饰的,这些修饰可能是通过一个类似于FCKeditor编辑加注了HTML修饰符的文本,如果自动转义的话显示的就是保护HTML标签的源文件。

1、article_detail视图函数中应拿到文章对象传入模板中

def article_detail(request, username, article_id):
    user = UserInfo.objects.filter(username=username).first()
    blog = user.blog
    article_obj = models.Article.objects.filter(pk=article_id).first()

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

2、模板语法一旦检查到标签字符串都会进行转义

  首先需要确认网站文章内容保存的并不是一个文本,而是一堆标签字符串。这样编辑文章时才会有各种各样的样式。

  将文章内容直接传进模板中。

{% extends "base.html" %}

{% block content %}
    <h3 class="text-center">{{ article_obj.title }}</h3>
    <div class="cont">
        {{ article_obj.content }}
    </div>
{% endblock %}

article_detail.html

  但是直接复制网站的html源代码进文章内容中,显示是不正确的。

  

  如上所示:将<h1>hello</h1>存进数据库,当服务器传给浏览器的时候,却变成了&lt;h1&gt;hello&lt;/h&gt;,浏览器按特殊符号渲染,因此显示为<h1>hello</h1>。

  

  由此可见,模板语法一旦检查到标签字符串都会进行转义。

3、在Django中关闭HTML的自动转义

  如果是一个单独的变量我们可以通过过滤器“|safe”的方式告诉Django这段代码是安全的不必转义。比如:

<p>这行代表会被自动转义</p>: {{ data }}
<p>这行代表不会被自动转义</p>: {{ data|safe }}

  其中第二行我们关闭了Django的自动转义。
  我们还可以通过{%autoescape off%}的方式关闭整段代码的自动转义,比如下面这样:

{% autoescape off %}
    Hello {{ name }}
{% endautoescape %}

  

原文地址:https://www.cnblogs.com/xiugeng/p/9424825.html

时间: 2024-10-19 06:19:38

文章详情页的相关文章

博客2.0--第一版文章详情页留念

新版文章详情页>>http://blog.51cto.com/itstyle/2127815 原文地址:http://blog.51cto.com/51ctoblog/2129401

6 功能4:文章详情页

1.文章详情页的设计 # 文章详情页 re_path(r'^(?P<username>\w+)/articles/(?P<article_id>\d+)$', views.article_detail, name='article_detail'), 2.文章详情页的数据构建 def article_detail(request, username, article_id): """文章详情页""" user_obj =

BBS - 文章详情页

一. 文章详情页的设计和数据构建 url.py # 文章详情页 re_path('^(?P<username>\w+)/articles/(?P<article_id>\d+)$', views.article_detail), # \w+:数字和字母 views.py def get_query_data(username): # 查询相关的数据,获取分类的数据 ''' 由于数据很多个地方需要用到,所以可以解耦出来,单独写一个函数 :param username: :return

Django 项目试炼blog(6) -- 文章详情页1 -- 点赞功能

url #文章详情页 re_path(r'(?P<username>\w+)/article/(?P<article_id>\d+)/$',views.article), # 点赞 path('up_down/', views.up_down), views from django.db.models import F def up_down(request): sign = request.POST.get('sign') sign = json.loads(sign) # 前端

如何在ecshop文章详情页增加文章描述

1.准备文件:前台article.php 后台 admin/article.php   和   admin/templates/article_info.htm2.数据库: 执行下面语句(如有需要,则更改表头ecs)ALTER  TABLE  `esc_article`  ADD  `article_desc` LONGTEXT NOT  NULL  AFTER  `keywords`也可到phpMyAdmin 中 找到表 ecs_article, 添加字段article_desc, 属性设置如

文章详情页文章评论功能

一.文章评论功能实现流程 文章评论包含两种评论,根评论:对文章的评论:子评论:对评论的评论.两者的区别在于是否存在父评论. 实现流程:1.构建样式:2.提交根评论:3.显示根评论(分为render显示和Ajax显示):4.提交子评论:5.显示子评论(分为render显示和Ajax显示):6.评论树显示(博客园是楼层显示). 二.构建评论样式 1.article_detail.html: {# 文章点赞,清除浮动 #} <div class="clearfix"> <d

Django 项目试炼blog(7) -- 文章详情页2 -- 前端样式的继承与楼评论显示

views from django.db import transaction def comment(request): article_id = request.POST.get('article_id') content = request.POST.get('content') pid = request.POST.get('parent_id') #事务操作 生成评论,文章数据中评论总数自动+1(同时执行) with transaction.atomic(): comm_obj = C

ecshop不同文章分类 不同文章详情页模板

修改article.php 1 <?php 2 if(isset($article) && $article['cat_id'] > 2 && $article['cat_id'] <>13) 3 { 4 $smarty->display('article.dwt', $cache_id); 5 } 6 elseif($article['cat_id'] == 13) 7 { 8 $smarty->display('article13.d

Django学习之实现文章详情页面的跳转

1.由于不支持博客首页到文章详情页的跳转,只能打开第一篇文章的详情页 2.所以需要做以下工作: 设计文章详情页的url,完善视图函数逻辑,实现首页跳转 /blog/detail =>不能指定某一篇文章 /blog/detail/1 => 博客唯一id唯1的文章 /blog/detail/2 => 博客唯一id唯2的文章 /blog/detail/3 => 博客唯一id唯3的文章 /blog/detail/...... 获取URL路径参数:<> 页面跳转:href指定ht