切日期:
from django.db.models.functions import TruncMonth
Sales.objects
.annotate(month=TruncMonth('timestamp')) #创建month列,列下面放切好的时间
.values('month') #以month分组
.annotate(c=Count('id')) #以id计数
.values('month', 'c') #显示month和id数据
url设计:
有原来的三条变成一条了
后端视图的形参利用* **来兼容
# url(r'^(?P<username>w+)/(?P<category>category)/(?P<param>d+)/',views.site),
# url(r'^(?P<username>w+)/(?P<tag>tag)/(?P<param>d+)/',views.site),
# url(r'^(?P<username>w+)/(?P<archive>archive)/(?P<param>w+)/',views.site),
url(r'^(?P<username>w+)/(?P<condition>category|tag|archive)/(?P<params>.*)/',views.site),
自定义inclusion_tag:
原理:
调用标签 传入参数 触发自定义函数提代码运行 将函数返回值传个另外页面 渲染完毕之后 再展示到调用该函数的位置
1.在应用下新建一个名字必须叫templatetags的文件夹
2.在该文件夹下新建一个任意名的py文件
3.在该文件中固定写以下局势
from django.template import Library
register = Library()
4.利用django提供的好的装饰器
@register.inclusion_tag('login.html')
5.HTML中:
{% load my_tag %}
{% left_menu username %}
前后端取消转义:
前端 |safe
from django.utils.safestring import mark_safe
后端 mark_safe('<a>我是a</a>')
HTML
{% extends 'base.html' %}
{% block css %}
<style>
#div_digg {
float: right;
margin-bottom: 10px;
margin-right: 30px;
font-size: 12px;
width: 128px;
text-align: center;
margin-top: 10px;
}
.diggit {
float: left;
width: 46px;
height: 52px;
background: url('/static/image/upup.gif') no-repeat;
text-align: center;
cursor: pointer;
margin-top: 2px;
padding-top: 5px;
}
.buryit {
float: right;
margin-left: 20px;
width: 46px;
height: 52px;
background: url('/static/image/downdown.gif') no-repeat;
text-align: center;
cursor: pointer;
margin-top: 2px;
padding-top: 5px;
}
.clear {
clear: both;
}
.diggword {
margin-top: 5px;
margin-left: 0;
font-size: 12px;
color: gray;
}
</style>
{% endblock %}
{% block content %}
<h1>{{ article_obj.title }}</h1>
{{ article_obj.content|safe }}
{# 点赞点踩前端样式#}
<div>
<div id="div_digg">
<div class="diggit action" >
<span class="diggnum" id="digg_count">{{ article_obj.up_num }}</span>
</div>
<div class="buryit action">
<span class="burynum" id="bury_count">{{ article_obj.down_num }}</span>
</div>
<div class="clear"></div>
<div class="diggword" id="digg_tips">
<span style="color: red" id="id_info"></span>
</div>
</div>
</div>
<script>
$('.action').click(function () {
var isUp = $(this).hasClass('diggit');
var $spanEle = $(this).children();
$.ajax({
url:'/up_or_down/',
type:'post',
data:{'is_up':isUp,'article_id':{{ article_obj.pk }},'csrfmiddlewaretoken':'{{ csrf_token }}'},
success:function (data) {
if (data.code == 2000){
$('#id_info').html(data.msg);
$spanEle.text(Number($spanEle.text()) + 1); #前端点赞点踩显示效果+1
}else{
$('#id_info').html(data.msg)
}
}
})
})
</script>
{% endblock %}
views
from django.db.models import Count
def site(request,username,*args,**kwargs):
user_obj = models.Userinfo.objects.filter(username=username).first()
if not user_obj: # 当用户不存在的时候返回404页面
return render(request,'error.html')
blog = user_obj.blog
username = user_obj.username
article_list = models.Article.objects.filter(blog=blog) # 当前用户所有的文章
if kwargs: # 判断kwargs是否有值 如果有值 你一个对上面的article_list再做一层筛选
condition = kwargs.get('condition')
params = kwargs.get('params')
if condition == 'category':
article_list = article_list.filter(category_id=params)
elif condition == 'tag':
article_list = article_list.filter(tag__id=params)
elif condition == 'archive':
# 2018-1
year,month = params.split('-')
article_list = article_list.filter(create_time__year=year,create_time__month=month)
"""侧边渲染相关"""
category_list = models.Category.objects.filter(blog=blog).annotate(c=Count('article__id')).values_list('category_name','c','pk') # 查询当前用户每一个的分类及分类下的文章数
tag_list = models.Tag.objects.filter(blog=blog).annotate(c=Count('article')).values_list('tag_name','c','pk') # 查询当前用户每一个标签及标签下的文章数
date_list = models.Article.objects.filter(blog=blog).annotate(month=TruncMonth('create_time')).values('month').annotate(c=Count('pk')).values_list('month','c') # pk:会自动帮你查找到当前表的主键字段
return render(request,'site.html',locals())
def article_detail(request,username,article_id):
article_obj = models.Article.objects.filter(pk=article_id).first()
blog = article_obj.blog
return render(request,'article_detail.html',locals())
import json
def up_or_down(request):
back_dic = {"code":None,'msg':''}
if request.is_ajax():
is_up = request.POST.get('is_up') # 你拿到的是js格式的布尔值 对应到python里面就是字符串
is_up = json.loads(is_up) # 利用json模块 将字符串形式转成python里面的布尔值
article_id = request.POST.get('article_id')
if request.user.is_authenticated(): # 1.先判断用户是否登陆
article_obj = models.Article.objects.filter(pk=article_id).first()
if article_obj: # 2.判断当前文章是否就是当前用户写的
if not article_obj.blog.userinfo.pk == request.user.pk:
is_click = models.UpAndDown.objects.filter(user=request.user,article=article_obj)
if not is_click: # 3.判断当前文章是否已经被当前用户点过了
if is_up: # 4.记录数据 1.到底是点赞还是点踩 2.两张表里面同步记录
models.Article.objects.filter(pk=article_id).update(up_num = F('up_num') + 1)
else:
models.Article.objects.filter(pk=article_id).update(down_num=F('down_num') + 1)
models.UpAndDown.objects.create(user=request.user,article=article_obj,is_up=is_up)
back_dic['code'] = 2000
back_dic['msg'] = '点赞成功' if is_up else '点踩成功' # 三元表达式 应用
else:
back_dic['code'] = 2001
back_dic['msg'] = '你已经点过了'
else:
back_dic['code'] = 2002
back_dic['msg'] = '你个臭不要脸 不能给自己点'
else:
back_dic['code'] = 2003
back_dic['msg'] = '未知错误'
else:
back_dic['code'] = 2004
back_dic['msg'] = mark_safe('请先<a href="/login/">登陆</a>')
return JsonResponse(back_dic)