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>發佈於  {{ article.create_time|date:"Y-m-d H:i" }}</span>   <span class="glyphicon glyphicon-comment"></span><a href="">評論({{ article.comment_count }})</a>   <span class="glyphicon glyphicon-thumbs-up"></span><a href="">點贊({{ article.up_count }})</a> </div> </div> <hr> {% endfor %} </div> {% endblock %}
兩種方法: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轉義了給你變成了特殊符號。做爲開發人員,在用戶提交的時候,不該該容許他提交。