BBS - 文章詳情頁

 

 

一. 文章詳情頁的設計和數據構建

  url.pycss

 

# 文章詳情頁
    re_path('^(?P<username>\w+)/articles/(?P<article_id>\d+)$', views.article_detail),  # \w+:數字和字母

 

 

  views.pyhtml

def get_query_data(username):  # 查詢相關的數據,獲取分類的數據
    '''
    因爲數據不少個地方須要用到,因此能夠解耦出來,單獨寫一個函數
    :param username:
    :return:
    '''

    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(
        "title", "c")
    tag_list = models.Tag.objects.filter(blog=blog).values("pk").annotate(c=Count("article__title")).values("title",
                                                                                                            "c")

    from django.db.models.functions import TruncMonth
    date_list = models.Article.objects.filter(user=user).annotate(month=TruncMonth("create_time")).values(
        "month").annotate(c=Count("title")).values("month", "c")

    return {"blog": blog, "cate_list": cate_list, "tag_list": tag_list, "date_list": date_list} def article_detail(request, username, article_id):  # url:127.0.0.1:8000/mm/articles/1

    context = get_query_data(username)

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

 

  base.html(繼承)python

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <link rel="stylesheet" href="/static/blog/bs/css/bootstrap.css">
    <style>
        *{
            margin: 0;
            padding: 0;
        }
        .header{
            width: 100%;
            height: 60px;
            background-color: #369;

        }
        .content .title{
            font-size: 18px;
            font-weight: 100;
            line-height: 60px;
            color: white;
            margin-left: 20px;
        }
        .backend{
            float: right;
            color: white;
            text-decoration: none;
            font-size: 14px;
            margin-top: 10px;
            margin-right: 15px;
        }
        .pub_info{
            margin-top: 10px;
            color: darkgrey;
        }
    </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">
            <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>

 

  home_site.htmldjango

{% extends 'base.html' %} // 繼承base.html

{% block content %}
    <div class="article_list">
                {% for article in article_list %}
                    <div class="article_item clearfix">  {# clearfix:清除浮動 #}
                        <h5><a href="">{{ article.title }}</a></h5>
                        <div class="article_desc">

                            <span class="media-right">
                                {{ article.desc }}
                            </span>
                        </div>
                        <div class="small pub_info pull-right">

                            <span>發佈於&nbsp&nbsp{{ article.create_time|date:"Y-m-d H:i" }}</span>&nbsp&nbsp
                            <span class="glyphicon glyphicon-comment"></span><a href="">評論({{ article.comment_count }})</a>&nbsp&nbsp
                            <span class="glyphicon glyphicon-thumbs-up"></span><a href="">點贊({{ article.up_count }})</a>
                        </div>

                    </div>

                    <hr>
                {% endfor %}

            </div>
{% endblock %}

 

二. 文章詳情頁的inclution_tag(定義本身的標籤)

  樣式和數據結合成一個總體

兩種方法:1是能夠用函數get_query_data (構建函數,傳到模板文件裏邊去,如上邊那種方法)bootstrap

     2是能夠用inclution_tag(方法二,樣式和數據結合成一個總體)瀏覽器

  my_tags.py安全

# -*- coding:utf-8 -*-

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

# inclution_tag

# 本身建立一個標籤

from django import template

register = template.Library()

@register.simple_tag
def multi_tag(x, y):
    return x*y


# 將獲得的數據直接交給"classification.html"渲染出來一個html頁面
@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(
        "title", "c")
    tag_list = models.Tag.objects.filter(blog=blog).values("pk").annotate(c=Count("article__title")).values("title",
                                                                                                            "c")

    from django.db.models.functions import TruncMonth
    date_list = models.Article.objects.filter(user=user).annotate(month=TruncMonth("create_time")).values(
        "month").annotate(c=Count("title")).values("month", "c")

    return {"blog": blog, "cate_list": cate_list, "tag_list": tag_list, "date_list": date_list}
# 先解讀上邊這些數據,而後返回一個字典給classfication.html,渲染成一個真正的html

  定義好標籤以後,是在模板裏邊去使用。函數

  article_detail.htmlurl

{% extends "base.html" %}

{% block content %}
    {% load my_tags %}  //要先load下 ,至關於python的import
    {% multi_tag 3 9 %} // 27
{% endblock %}

 

  base.htmlspa

<div class="col-md-3 menu"> {% load my_tags %}  //把原來在base.html裏邊的col-md-3的內容單獨做爲一個classification.html,而後再load下把它引入進來。
            {% get_classification_style username %} //把那一堆html代碼又返回到這個地方來了
</div>

 

  classificition.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.title }}">{{ tag.title }}</a>({{ tag.c }})</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.title }}">{{ cate.title }}</a>({{ cate.c }})</p>
        {% endfor %}

    </div>
    </div>

    <div class="panel panel-info">
    <div class="panel-heading">隨筆歸檔</div>
    <div class="panel-body">
        {% for date in date_list %}
        <p><a href="/{{ username }}/archive/{{ date.month|date:"Y-m" }}">{{ date.month|date:"Y-m" }}</a>({{ date.c }})</p>
        {% endfor %}

    </div>
    </div>
</div>

 

  views.py的視圖函數訪問home_site.html進行渲染,同時繼承了base.html進行渲染,渲染base的時候會去調用get_classification_style,先取數據再去交給classification.html這套樣式渲染,渲染以後的結果再放到這個col-md-3中,

 

  views.py

def home_site(request, username, **kwargs):
    '''
    我的站點視圖函數
    :param request:
    :return:
    '''
    user = UserInfo.objects.filter(username=username).first()
    if not user:
        return render(request, "not_found.html")

    article_list = models.Article.objects.filter(user=user)

    if kwargs:
        condition = kwargs.get("condition")
        param = kwargs.get("param")

        if condition == "category":
            article_list = article_list.filter(category__title=param)
        elif condition == "tag":
            article_list = article_list.filter(tags__title=param)
        else:
            year, month = param.split("-")
            article_list = article_list.filter(create_time__year=year, create_time__month=month)

    return render(request, "home_site.html", {"username": username, "article_list": article_list})

def get_query_data(username):
    '''
    因爲數據不少個地方須要用到,因此能夠解耦出來,單獨寫一個函數
    :param username:
    :return:
    '''

    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(
        "title", "c")
    tag_list = models.Tag.objects.filter(blog=blog).values("pk").annotate(c=Count("article__title")).values("title",
                                                                                                            "c")

    from django.db.models.functions import TruncMonth
    date_list = models.Article.objects.filter(user=user).annotate(month=TruncMonth("create_time")).values(
        "month").annotate(c=Count("title")).values("month", "c")

    return {"blog": blog, "cate_list": cate_list, "tag_list": tag_list, "date_list": date_list}


def article_detail(request, username, article_id):return render(request, "article_detail.html", locals())

 

三.文章詳情頁渲染的標籤字符串轉義

  views.py

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())

 

  article_detail.html 

{% extends "base.html" %}

{% block content %}
{#    {% load my_tags %}#}
{#    {% multi_tag 3 9 %}#}
    <h3 class="text-center">{{ article_obj.title }}</h3>
    <div class="cont">
       {{ article_obj.content |safe }} {# 加這個是爲了告訴django的模板不要給我作任何轉義,爲了安全性;網頁源碼#}
    </div>

{% endblock %}

  做爲一個用戶提交了JS代碼,至關於我能夠控制了其餘看到這篇文章的用戶的瀏覽器了,能夠經過js代碼去控制其餘信息。這叫XSS惡意攻擊。

Django加了safe轉義了給你變成了特殊符號。做爲開發人員,在用戶提交的時候,不該該容許他提交。

相關文章
相關標籤/搜索