一、文章详细页
文章详细页: 1.链接: 2.url分配: re_path('(?P\w+)/articles/(?P \d+)/$',views.article_detail), # 注意放在上面,否则下面得会覆盖上面得! re_path('(?P \w+)/articles/(?P \d+)/$',views.article_detail), re_path('(?P \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 templateregister = template.Library()@register.simple_tagdef mul(x,y): return x*yfrom 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}
homesite {% load my_tags %}{
{ blog.title }}{% get_menu username %}{% block content %} {% endblock content %}
{% extends 'base.html' %}{% block content %} {% load my_tags %}{% for article in article_list %}{% endblock content %}{
{ article.desc }}发布于 { { article.create_time|date:'Y-m-d' }} 评论({ { article.comment_count }}) 赞({ { article.up_count }})
{% endfor %}
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 %}{ { article.title }}
{ { article.articledetail.content|safe }}{% csrf_token %}{% endblock content%}{ { article.up_count }}{ { article.down_count }}
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.文章详细内容:{ { article.title }}
{ { article.articledetail.content|safe }}为什么要加 safe? { { article.articledetail.content|safe }},告诉django不要转义! django 框架会将标签转义! 库:Hello world
django: <h1>Hello world</h1> 浏览器渲染后:Hello world
django 得模板问题:遇到标签转译为特殊字符,发送给客户端。 防止用户存一些 js 如果交给浏览器就会加载,实现攻击,恶意破环! 然而,就不应该让标签,不合法得类似
5.个人 站点 样式(皮肤)不一样:
二、点赞、踩灭
注意点: 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:
{ { article.up_count }}{ { article.down_count }}
import jsonfrom django.http import JsonResponsefrom django.db.models import Fdef 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/' }});
知识点:
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 就可以渲染!但是:写在静态文件中: 不能使用 { {}} 模板语言! alert("{ { name }}") 因为:没有任何过程去渲染!! js是浏览器再发一次请求! 可以: js: var val = $('#hid_name').val()