BBS - 文章詳細頁、點贊、踩滅

1、文章詳細頁

 

文章詳細頁:
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}
my_tags.py
 
<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>
menu.html

 

<!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>
base.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">
                    發佈於&nbsp;&nbsp;&nbsp;
                    <span>{{ article.create_time|date:'Y-m-d' }}</span>&nbsp;&nbsp;&nbsp;&nbsp;
                    <span class="glyphicon glyphicon-comment"></span>評論({{ article.comment_count }})&nbsp;&nbsp;&nbsp;
                    <span class="glyphicon glyphicon-thumbs-up"></span>贊({{ article.up_count }})
                </div>
            </div>
            <hr>

        {% endfor %}

    </div>
{% endblock content %}
homesite.html

 

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

 

{% 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%}
article_detail.html

 

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

 

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:
&lt;h1&gt;Hello world&lt;/h1&gt;
瀏覽器渲染後:
<h1>Hello world</h1>

django 得模板問題:遇到標籤轉譯爲特殊字符,發送給客戶端。
防止用戶存一些 js 若是交給瀏覽器就會加載,實現攻擊,惡意破環!

然而,就不該該讓標籤,不合法得相似<script>入庫,後續beautifulSoup會學!

5.我的 站點 樣式(皮膚)不同:
<link rel="stylesheet" href="/static/theme/{{ blog.theme }}">

 

2、點贊、踩滅

    

 


注意點:
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/'
    }

});
article_detail.js

 

知識點: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()
相關文章
相關標籤/搜索