文章詳細頁:
1.連接:
<div><h5><a href="/blog/{{ article.user.username }}/articles/{{ article.pk }}">{{ article.title }}</a></h5></div>
2.url分配:
re_path('(?P<username>\w+)/articles/(?P<article_id>\d+)/$',views.article_detail),
# 注意放在上面,不然下面得會覆蓋上面得!
re_path('(?P<username>\w+)/articles/(?P<article_id>\d+)/$',views.article_detail),
re_path('(?P<username>\w+)/$',views.homesite)
3.模板繼承:
由於 homesite 與 article_detail 總體頁面樣式,同樣,只有內容部分不同!!
繼承,只傳樣式,沒數據,怎麼辦? (include_tag)
知識點:
1.inclue 沒有盒子得概念,某一塊html直接拿來用!
{% include 'menu.html' %}
2.extends 可重寫,可複用,有盒子得概念,整個頁面繼承.
{% extends 'base.html' %}
3.自定義標籤
/blog/templatetags/my_tags.py
from django import template
register = template.Library()
@register.simple_tag
def mul(x,y):
return x*y
4.include_tag (自定義標籤生成了html)
# 將 模板與數據 結合起來 (若是寫函數也能夠傳數據,可是將模板與數據分開了)
/templatetags/my_tags.py
{% load my_tags %}
{% get_menu username %}
@register.inclusion_tag('menu.html')
def get_menu(username):
...
return {} 返回字典 去渲染 menu.html
做用:
include_tag 能解決複用問題,數據重複問題; 既有數據處理,又有模板渲染!
# -*- coding:utf-8 -*- from django import template register = template.Library() @register.simple_tag def mul(x,y): return x*y from blog.models import * @register.inclusion_tag('menu.html') def get_menu(username): # 當前站點得用戶對象 user = UserInfo.objects.filter(username=username).first() blog = user.blog # 查詢站點全部每個分類 以及 對應得文章數 分組!! from django.db.models import Count # 查詢站點全部每個分類 以及 對應得文章數 分組!! cate_list = Category.objects.filter(blog=blog).annotate(count = Count('article')).values('title','count') # 每個標籤以及對應得文章數 tag_list = Tag.objects.filter(blog=blog).annotate(count = Count('article')).values_list('title','count') # 查詢每個年月 日期 查詢 統計 date_list = Article.objects.filter(user=user).extra(select={"create_ym":"DATE_FORMAT(create_time,'%%Y-%%m')"}).values('create_ym').annotate(c = Count('nid')).values_list('create_ym','c') return {'username':username,'cate_list':cate_list,'tag_list':tag_list,'date_list':date_list}
<div class="menu"> <div class="panel panel-info"> <div class="panel-heading">個人分類</div> <div class="panel-body"> {% for cate in cate_list %} <p><a href="/blog/{{ username }}/cate/{{ cate.title }}">{{ cate.title }}({{ cate.count }})</a></p> {% endfor %} </div> </div> <div class="panel panel-success"> <div class="panel-heading">個人標籤</div> <div class="panel-body"> {% for tag in tag_list %} <p><a href="/blog/{{ 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 date in date_list %} <p><a href="/blog/{{ username }}/archive/{{ date.0 }}">{{ date.0 }}({{ date.1 }})</a></p> {% endfor %} </div> </div> </div>
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>homesite</title> {% load my_tags %} <link rel="stylesheet" href="/static/bootstrap-3.3.7/css/bootstrap.css"> <link rel="stylesheet" href="/static/css/article_detail.css"> <script src="/static/js/jquery-3.2.1.min.js"></script> <script src="/static/bootstrap-3.3.7/js/bootstrap.min.js"></script> <style type="text/css"> *{padding: 0;margin: 0;} .header{ width: 100%; height: 40px; background-color: #336699; line-height: 40px; font-size: 16px; color: white;} .header p{ margin-left: 15px;} </style> </head> <body> <div class="header"> <p class="title">{{ blog.title }}</p> </div> <div class='container'> <div class="col-md-3"> {% get_menu username %} </div> <div class="col-md-8"> {% block content %} {% endblock content %} </div> </div> </body> </html>
{% extends 'base.html' %} {% block content %} {% load my_tags %} <div class="article_list"> {% for article in article_list %} <div class="article_item"> <div><h5><a href="/blog/{{ article.user.username }}/articles/{{ article.pk }}">{{ article.title }}</a></h5></div> <div class="row"> <div class="col-md-9 desc"> <p>{{ article.desc }}</p> </div> </div> <div class="small"> 發佈於 <span>{{ article.create_time|date:'Y-m-d' }}</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> {% endblock content %}
def homesite(request,username,**kwargs): # 當前站點得用戶對象 user = UserInfo.objects.filter(username=username).first() if not user: return HttpResponse('404') # 當前站點對象 blog = user.blog # 查詢當前站點對應得文章,以及分類,標籤,日期歸檔得文章 if not kwargs: article_list = Article.objects.filter(user=user) else: condition = kwargs.get('condition') param = kwargs.get('param') if condition == 'cate': article_list = Article.objects.filter(user=user, category__title=param) elif condition == 'tag': article_list = Article.objects.filter(user=user, tags__title=param) else: year, month = param.split('-') article_list = Article.objects.filter(user=user).filter(create_time__year=year, create_time__month=month) return render(request,'homesite.html',locals())
{% extends 'base.html' %} {% block content %} <h3 class="text-center">{{ article.title }}</h3> <div class="content"> {{ article.articledetail.content|safe }} </div> <input type="hidden" id="hid_article_pk" value="{{ article.pk }}"> <div id="div_digg"> <div class="diggit digg"> <span class="diggnum" id="digg_count">{{ article.up_count }}</span> </div> <div class="buryit digg"> <span class="burynum" id="bury_count">{{ article.down_count }}</span> </div> </div> <div id="digg_word" class="pull-right"></div> {% csrf_token %} <script src="/static/js/article_detail.js"></script> {% endblock content%}
def article_detail(request,username,article_id): user = UserInfo.objects.filter(username=username).first() blog = user.blog article = Article.objects.filter(pk=article_id).first() return render(request,'article_detail.html',locals())
4.文章詳細內容:
<h3 class="text-center">{{ article.title }}</h3>
<div class="content">
{{ article.articledetail.content|safe }}
</div>
爲何要加 safe?
{{ article.articledetail.content|safe }},告訴django不要轉義!
django 框架會將標籤轉義!
庫:
<h1>Hello world</h1>
django:
<h1>Hello world</h1>
瀏覽器渲染後:
<h1>Hello world</h1>
django 得模板問題:遇到標籤轉譯爲特殊字符,發送給客戶端。
防止用戶存一些 js 若是交給瀏覽器就會加載,實現攻擊,惡意破環!
然而,就不該該讓標籤,不合法得相似<script>入庫,後續beautifulSoup會學!
5.我的 站點 樣式(皮膚)不同:
<link rel="stylesheet" href="/static/theme/{{ blog.theme }}">
注意點:
1.
在js中使用模板{{}} 加"", 不加""就看成變量了,找不到。
if("{{ request.user.username }}"){}
2.
ajax實現,兩個按鈕綁定一個點擊事件。
前端:
var is_up = $(this).hasClass('diggit'); # true false
後臺:
is_up = json.loads(request.POST.get('is_up')) # 變成 boolean 由於是str
3.
from django.db import transaction
try:
with transaction.atomic(): # 事務!同進退,數據同步!!
是點贊仍是踩滅? 自+1 更新時 F 查詢得應用
ArticleUpDown.objects.create(is_up=is_up,article_id=article_id,user_id=user_id)
if is_up:
Article.objects.filter(pk=article_id).update(up_count = F("up_count") + 1)
else:
Article.objects.filter(pk=article_id).update(down_count = F("down_count") + 1)
except Exception as e:
須要返回上一次得 點擊狀況:
res['state'] = False
res['first_operate'] = ArticleUpDown.objects.filter(article_id=article_id,user_id=user_id).first().is_up
4.code:
<script src="/static/js/article_detail.js"></script>
<input type="hidden" id="hid_article_pk" value="{{ article.pk }}"> <input type="hidden" id="hid_username" value="{{ request.user.username }}"> <div id="div_digg"> <div class="diggit digg"> <span class="diggnum" id="digg_count">{{ article.up_count }}</span> </div> <div class="buryit digg"> <span class="burynum" id="bury_count">{{ article.down_count }}</span> </div> </div> <div id="digg_word" class="pull-right"></div>
import json from django.http import JsonResponse from django.db.models import F def poll(request): is_up = json.loads(request.POST.get('is_up')) # 得變成 boolean article_id = request.POST.get('article_id') user_id = request.user.pk res = {'state':True} from django.db import transaction try: with transaction.atomic(): # 事務 ArticleUpDown.objects.create(is_up=is_up,article_id=article_id,user_id=user_id) if is_up: Article.objects.filter(pk=article_id).update(up_count = F("up_count") + 1) else: Article.objects.filter(pk=article_id).update(down_count = F("down_count") + 1) except Exception as e: res['state'] = False res['first_operate'] = ArticleUpDown.objects.filter(article_id=article_id,user_id=user_id).first().is_up return JsonResponse(res)
$('#div_digg .digg').click(function () { var username = $('#hid_username').val(); if(username){ var is_up = $(this).hasClass('diggit'); var article_id = $('#hid_article_pk').val(); var csrfmiddlewaretoken = $('input[name="csrfmiddlewaretoken"]').val(); $.ajax({ url:'/blog/poll/', type:'post', data:{ is_up:is_up, article_id:article_id, csrfmiddlewaretoken:csrfmiddlewaretoken }, success:function (data) { if(data.state){ // 贊或者滅 成功 if(is_up){ var val = parseInt($('#digg_count').text())+1; $('#digg_count').text(val) }else{ var val = parseInt($('#bury_count').text())+1; $('#bury_count').text(val) } }else{ // 重複操做 失敗 console.log(data.first_operate); if(data.first_operate){ $('#digg_word').html('您已經推薦過').css({"color":"red","margin-right":"-111px",'margin-top':"75px"}) }else{ $('#digg_word').html('您已經反對過').css({"color":"red","margin-right":"-111px",'margin-top':"75px"}) } } } }) }else{ location.href = '/login/' } });
知識點:css
1.js 注意事項:
if(){ # 何時爲 true / false ?
}else{
}
1.
if([]){
alert(123)
}
彈, [] 空對象, object 對於對象 boolean 是真!!
2.
if({}){
alert(456)
}
彈, {} 空對象,object 對於對象 boolean 是真!
3.
if(""){
alert(789)
}
不彈
對於 js 除了""外,其它得都爲對象,
4.
if("999"){
alert(789)
}
彈 有值就爲 真
2.js與模板語言:
js 能夠寫模板語言{{}},可是要寫到 html 裏面。 "{{ }}" render 就能夠渲染!
可是:寫在靜態文件中: <script src="/static/js/test.js"></script> 不能使用 {{}} 模板語言! alert("{{ name }}") 由於:沒有任何過程去渲染!! js是瀏覽器再發一次請求! 能夠: <input id="hid_name" type="hidden" value={{name}}> js: var val = $('#hid_name').val()