BBS 项目(五)
目录
实现伪静态(人工智能版)
路由整合
# 三个路径混成一个路径
# http://127.0.0.1:8001/liuqingzheng/category/3.html
# http://127.0.0.1:8001/liuqingzheng/tag/3.html
# http://127.0.0.1:8001/liuqingzheng/archive/2020/06.html
# http://127.0.0.1:8001/liuqingzheng/archive/2020-06.html
re_path('^(?P<username>\w+)/(?P<condition>category|tag|archive)/(?P<params>.*).html$', views.personal_site),
视图函数
def personal_site(request, username, **kwargs): user = models.UserInfo.objects.filter(username=username).first() if user: article_list = user.blog.article_set.all() if kwargs: 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': param_year, param_month = params.split('/') article_list = article_list.filter(create_time__year=param_year, create_time__month=param_month) return render(request, 'site.html', locals()) else: return render(request, '404.html')
左侧标签,分类,归档写成inclusion_tag
left.py
from django import template register = template.Library() from blog import models from django.db.models.functions import TruncMonth from django.db.models import Count @register.inclusion_tag('left.html') def left_inclusion_tag(username): user=models.UserInfo.objects.filter(username=username).first() category_list = models.Category.objects.filter(blog=user.blog).annotate(count=Count('article')).values('count', 'name', 'id') tag_list = models.Tag.objects.filter(blog=user.blog).annotate(count=Count('article')).values_list('count', 'name', 'id') month_list = models.Article.objects.filter(blog=user.blog).annotate(month=TruncMonth('create_time')).values( 'month').annotate(count=Count('id')).values_list('month', 'count') return {'username':username,'category_list':category_list,'tag_list':tag_list,'month_list':month_list}
left.html
<div>
<div class="panel panel-success">
<div class="panel-heading">
<h3 class="panel-title">我的标签</h3>
</div>
<div class="panel-body">
{% for tag in tag_list %}
<p><a href="/{{ username }}/tag/{{ tag.2 }}.html">{{ tag.1 }}({{ tag.0 }})</a></p>
{% endfor %}
</div>
</div>
<div class="panel panel-info">
<div class="panel-heading">
<h3 class="panel-title">我的分类</h3>
</div>
<div class="panel-body">
{% for category in category_list %}
<p>
<a href="/{{ username }}/category/{{ category.id }}.html">{{ category.name }}({{ category.count }})</a>
</p>
{% endfor %}
</div>
</div>
<div class="panel panel-info">
<div class="panel-heading">
<h3 class="panel-title">随笔档案</h3>
</div>
<div class="panel-body">
{% for month in month_list %}
<p>
<a href="/{{ username }}/archive/{{ month.0|date:'Y/m' }}.html">{{ month.0|date:'Y年m月' }}({{ month.1 }})</a>
</p>
{% endfor %}
</div>
</div>
</div>
使用
这样哪里需要左侧样式直接cpoy就可以了
{% load left %}
{% left_inclusion_tag username %}
文章详情页面搭建
模仿博客园的样式搭建,图片要下载下来有防盗链
{% extends 'base.html' %}
{% block js %}
<link rel="stylesheet" href="/static/css/article_css.css">
{% endblock %}
{% block title %}
{{ article.title }} --- 文章
{% endblock %}
{% block site_name %}
{{ article.blog.site_name }}
{% endblock %}
{% block main %}
<div>
<div class="text-center">
<h3>{{ article.title }}</h3>
</div>
<hr>
{{ article.content|safe }}
</div>
{# 点赞 #}
<div id="div_digg">
<div class="diggit action">
<span class="diggnum" id="digg_count">{{ article.up_num }}</span>
</div>
<div class="buryit action">
<span class="burynum" id="bury_count">{{ article.down_num }}</span>
</div>
<div class="clear"></div>
<div class="diggword" id="digg_tips">
</div>
</div>
{% endblock %}
{% block footer %}
<div>
<br><br><br><br><br>
</div>
<div class="footer text-center" style="background-color: rgb(243,243,243)">
<footer id="footer" class="footer">
<div>
<!--done-->
Copyright © 2022 HammerZe
<br><span id="poweredby">Powered by .NET 6 on Kubernetes</span>
<span class="esa-copyright">& Theme <a href="https://github.com/esofar/cnblogs-theme-silence"
target="_blank">Silence v3.0.0</a></span></div>
</footer>
</div>
{% endblock %}
{% block footer_js %}
<script>
{# 点赞和点踩统一,不分开写 #}
$('.action').click(function () {
var is_up = $(this).hasClass('diggit')
/*alert(is_up),如果点了赞就是true,点了踩就是false*/
var span= $(this).children('span')
$.ajax({
url: '/upanddown/',
method: 'post',
data: {article_id: '{{ article.id }}', is_up: is_up, 'csrfmiddlewaretoken': '{{ csrf_token }}'},
success: function (data) {
console.log(data)
{#显示点赞/点踩提示信息#}
$('#digg_tips').html(data.msg)
{#点赞数显示#}
if (data.status=='100'){
//let num=Number(span.html())+1
span.html(Number(span.html())+1)
}
}
})
})
</script>
{% endblock %}
文章点赞点踩样式
<div id="div_digg"> <div class="diggit action"> <span class="diggnum" id="digg_count">{{ article.up_num }}</span> </div> <div class="buryit action"> <span class="burynum" id="bury_count">{{ article.down_num }}</span> </div> <div class="clear"></div> <div class="diggword" id="digg_tips"> </div> </div>
#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; } .diggword { margin-top: 5px; margin-left: 0; font-size: 12px; color: red; }
文章点赞点踩后端
后端
def upanddown(request): if request.is_ajax(): response = {'status': 100, 'msg': None} if request.user.is_authenticated: article_id = request.POST.get('article_id') is_up = json.loads(request.POST.get('is_up')) res = models.UpAndDown.objects.filter(article_id=article_id, user=request.user) if res: # 点过了 response['status'] = 102 response['msg'] = '你已经点过了' return JsonResponse(response) # 事务操作 with transaction.atomic(): if is_up: models.Article.objects.filter(id=article_id).update(up_num=F('up_num') + 1) response['msg'] = '点赞成功' else: models.Article.objects.filter(id=article_id).update(down_num=F('down_num') + 1) response['msg'] = '点踩成功' models.UpAndDown.objects.create(user=request.user, article_id=article_id, is_up=is_up) return JsonResponse(response) else: response['status'] = '101' response['msg'] = '请去<a href="/login/">登录</a>' return JsonResponse(response)
前端
$('.action').click(function () { var is_up=$(this).hasClass('diggit') var span= $(this).children('span') $.ajax({ url:'/upanddown/', method:'post', //谁(当前登录用户)对那篇文章点赞或点踩 data:{article_id:'{{ article.id }}',is_up:is_up,'csrfmiddlewaretoken':'{{ csrf_token }}'}, success:function (data) { console.log(data) $('#digg_tips').html(data.msg) if (data.status=='100'){ //let num=Number(span.html())+1 span.html(Number(span.html())+1) } } }) })

浙公网安备 33010602011771号