咱们在建立文章时,会在数据库中存储文章建立的时间这样的字段,通常用的都是datetime类型,记录文章建立的年月日和时分秒,因此咱们直接使用文章的建立时间分类是没法实现文章的按年月归档的,由于每一篇文章的时间是不同的,因此咱们在使用ORM查询时就没法作到按年月分类的需求,这是就须要额外的SQL语句来实现,在SQL语句中有一个很重的时间格式化的方法:date_formatcss
咱们可使用ORM中执行SQL语句原生用法的方法:extrahtml
from blog import models from django.db.models import Count #假设咱们获得一个user对象 文章表中有一个create_time 字段
achive = models.Article.objects.filter(user=user).extra( select={"archive":"date_format(create_time,'%%Y-%%m')" } ).values("archive").annotate(c=Count('pk')).values("archive","c") #"pk" 在Django中代指表的主键
urls.py的配置python
from django.conf.urls import url from blog import views urlpatterns = [ url(r'^(\w+)/archive/(.+)/$',views.home), ]
views.pygit
try: year, mouth = args[1].split('-') logger.debug('年:{} 月:{}'.format(year, mouth)) article_list = models.Article.objects.filter(user=user).filter(create_time__year=year, create_time__month=mouth) except Exception as e: logger.error(str(e)) return HttpResponse('404')
备注:使用Django时,默认使用的UTC时间,而中国的时区为东八区,因此会在查询时间时带上一个+8的字样,因此经过fliter查找字段时,直接等于year或者month是没法查出须要的对象的,这是咱们须要在settings.py文件中,修改一个参数:USE_TZ = True 改成False 就能够了。ajax
点赞部分的HTML实现数据库
<div class="clearfix">
<div id="div_digg">
<div class="diggit">
<span class="diggnum" id="digg_count">{{ article.up_count }}</span>
</div>
<div class="buryit">
<span class="burynum" id="bury_count">{{ article.down_count }}</span>
</div>
<div class="clear"></div>
<div class="diggword" id="digg_tips" style="color: red;"></div>
</div>
</div>
// 备注;若是js的实现是做为一个静态文件导入时,须要在HTML页面中隐藏一个标签,这个标签存储咱们在静态文件中须要的值
<div class="info" article_id="{{ article.pk }}" username="{{ request.user.username }}" style="display: none"></div>
备注:在bootstarp中会自带一个清除父标签塌陷的样式类方法 (class="clearfix")django
点赞的相关css样式json
#div_digg { float: right; margin-bottom: 10px; margin-right: 30px; font-size: 12px; width: 125px; text-align: center; margin-top: 10px;
} .diggit { float: left; width: 46px; height: 52px; background: url('/static/img/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/img/downdown.gif') no-repeat; text-align: center; cursor: pointer; margin-top: 2px; padding-top: 5px;
} .clear { clear: both;
}
点赞帮点事件并发ajax请求服务器
$("#div_digg .action").click(function () { if ($(".info").attr("username")) { // 点赞或踩灭 经过判断有无某个样式类来区分是点赞仍是踩,以点赞中的diggit样式类参考,若是为点赞,则返回true,为踩,返回false
var is_up = $(this).hasClass("diggit"); var article_id = $(".info").attr("article_id"); $.ajax({ url: "/blog/up_down/", type: "post", data: { is_up: is_up, article_id: article_id, csrfmiddlewaretoken: $("[name='csrfmiddlewaretoken']").val(), }, success: function (data) { // console.log(data);
if (data.state) {// 对当前文章首次赞或者灭成功
if (is_up) { var val = $("#digg_count").text(); val = parseInt(val) + 1; $("#digg_count").text(val); } else { var val = $("#bury_count").text(); val = parseInt(val) + 1; $("#bury_count").text(val); } } else { // 重复提交
if (data.fisrt_action) { $("#digg_tips").html("您已经推荐过"); } else { $("#digg_tips").html("您已经反对过"); } setTimeout(function () { $("#digg_tips").html("") }, 1000) } } }) } else { // 没有登陆 就跳转登陆
location.href = "/login/" } });
点赞urls.py (ajax请求相关)并发
from django.conf.urls import url from blog import views urlpatterns = [ url(r"up_down/",views.up_down), ]
点赞处理ajax请求的视图函数
def up_down(request): article_id=request.POST.get('article_id') is_up=json.loads(request.POST.get('is_up')) user=request.user response={"state":True} try: models.ArticleUpDown.objects.create(user=user,article_id=article_id,is_up=is_up) models.Article.objects.filter(pk=article_id).update(up_count=F("up_count")+1) except Exception as e: response["state"]=False response["fisrt_action"]=models.ArticleUpDown.objects.filter(user=user,article_id=article_id).first().is_up return JsonResponse(response)
评论树和评论楼两种方式:
评论的相关路由
from django.conf.urls import url from blog import views urlpatterns = [ url(r"comment/",views.comment), url(r"comment_tree/(\d+)/",views.comment_tree), ]
评论的相关视图函数
def comment(request): print(request.POST) pid=request.POST.get("pid") article_id=request.POST.get("article_id") content=request.POST.get("content") user_pk=request.user.pk response={} if not pid: #根评论
comment_obj=models.Comment.objects.create(article_id=article_id,user_id=user_pk,content=content) else: comment_obj=models.Comment.objects.create(article_id=article_id,user_id=user_pk,content=content,parent_comment_id=pid) response["create_time"]=comment_obj.create_time.strftime("%Y-%m-%d") response["content"]=comment_obj.content response["username"]=comment_obj.user.username return JsonResponse(response) def comment_tree(request,article_id): ret=list(models.Comment.objects.filter(article_id=article_id).values("pk","content","parent_comment_id")) print(ret) return JsonResponse(ret,safe=False)
评论的HTML相关
<p>评论树</p>
<div class="comment_tree"> // 评论树内容相关 </div>
<hr>
<p>评论楼</p>
<p>评论列表</p>
<ul class="comment_list"> {% for comment in comment_list %} <li class="list-group-item">
<div>
<a href="">#{{ forloop.counter }}楼</a>
<span style="color: gray">{{ comment.create_time|date:"Y-m-d H:i" }}</span>
<a href=""><span>{{ comment.user.username }}</span></a>
<a class="pull-right reply_btn" username="{{ comment.user.username }}" comment_pk="{{ comment.pk }}"><span>回复</span></a>
</div> {% if comment.parent_comment_id %} <div class="pid_info well">
<p> {{ comment.parent_comment.user.username }}: {{ comment.parent_comment.content }} </p>
</div> {% endif %} <div class="con">
<p> {{ comment.content }} </p>
</div>
</li> {% endfor %} </ul> {% if request.user.username %} <div class="div_comment">
<p>昵称:<input type="text" id="tbCommentAuthor" class="author" disabled="disabled" size="50" value="{{ request.user.username }}"></p>
<p>评论内容</p>
<textarea name="" id="comment_content" cols="60" rows="10"></textarea>
<p>
<button id="comment_btn">提交评论</button>
</p>
</div> {% else %} <a href="/login/">登陆</a> {% endif %}
评论的js实现
<script> // 获取评论数据,展现评论树结构 $.ajax({ url: "/blog/comment_tree/" + '{{ article.pk }}/', success: function (data) { console.log(data); $.each(data, function (index, comment_dict) { var s = '<div class="comment_item" comment_id=' + comment_dict.pk + '> <span class="content">' + comment_dict.content + '</span> </div>' if (comment_dict.parent_comment_id) { // 子评论 var perid=comment_dict.parent_comment_id; $("[comment_id="+perid+"]").append(s); } else { // 根评论 $(".comment_tree").append(s); } }) } }); // 提交评论 var pid = ""; $("#comment_btn").click(function () { var article_id = $(".info").attr("article_id"); var content = $("#comment_content").val(); if (pid) { var index = content.indexOf("\n"); content = content.slice(index + 1) } $.ajax({ url: "/blog/comment/", type: "post", data: { article_id: article_id, content: content, pid: pid, csrfmiddlewaretoken: $("[name='csrfmiddlewaretoken']").val(), }, success: function (data) { console.log(data); var create_time = data.create_time; var content = data.content; var username = data.username; if (arg.status){
// 是根评论 var comment_li = '<li class="list-group-item"><div><span style="color: gray">' + create_time
+ '</span> <a href=""><span>' + username + '</span></a></div> <div class="con">
<p> ' + content + ' </p> </div> </li>'; $(".comment_list").append(comment_li);
}else{
// 是子评论
var parent_name = arg.parent_username;
var par_content = arg.parent_content;
var m = '<li class="list-group-item"><div><span>' + create_time + ' </span><span>' +
username + ' </span>' + '</div><div class="well">'+parent_name+':'
+par_content+'</div><div>' + content + '</div></li>';
$(".list-group").append(m);
}
// 清空文本框 $("#comment_content").val('');
// 清空pid pid = ""
}
})
});
// 回复按钮事件
$(".list-group-item .reply_btn").click(function () {
$("#comment_content").focus();
var v = "@" + $(this).attr("username") + "\n"; $("#comment_content").val(v);
//pid赋值 pid = $(this).attr("comment_pk") })
</script>
另外Django中也提供了发送邮件的方法,不须要咱们直接使用email模块
from django.core.mail import send_mail
1 首先去本身的邮箱申请,在设置里面找,申请开通smtp服务,我用的是163邮箱
2 在项目下settings.py中添加设置:
1 # 配置邮箱发邮件的相关功能 2 3 #这一项是固定的 4 EMAIL_BACKEND = 'django.core.mail.backends.smtp.EmailBackend' 5 # smtp服务的邮箱服务器 我用的是163 6 EMAIL_HOST = 'smtp.163.com' 7 # smtp服务固定的端口是25 8 EMAIL_PORT = 25 9 #发送邮件的邮箱 10 EMAIL_HOST_USER = 'xxxx@163.com' 11 #在邮箱中设置的客户端受权密码 12 EMAIL_HOST_PASSWORD = 'xxxx' 13 #收件人看到的发件人 <此处要和发送邮件的邮箱相同> 14 EMAIL_FROM = 'python<xxxx@163.com>'
3 配置好映射urls.py, 建立好视图,.... 这些步骤省略了.....找到相应视图后
4 在视图中调用以下函数 便可发送邮件:
1 from django.conf import settings 2 from django.core.mail import send_mail 3 from django.http import HttpResponse 4 ... 5 def send(request): 6 msg='<a href="哈哈哈" target="_blank">点击激活</a>' 7 send_mail('标题','内容',settings.EMAIL_FROM, 8 '目标邮箱', 9 html_message=msg) 10 return HttpResponse('ok')
注意要 导入 settings模块,和send_email模块
调用send_mail() 函数即发送邮件,具体参数以下
send_mail( 标题,文字内容,发件邮箱,目的邮箱,html标签内容 )