截止到现在,我们博客已经基本实现了该有的功能,但是,我们还没有为博客添加统计功能,在首页中有显示博文的数目、分类的数目以及标签的数目,这些数目其实可以直接在视图函数中写上,然后传递到模板。例如:
blog_nums = Blog.objects.count()
category_nums = Category.objects.count()
tag_nums = Tag.objects.count()
return render(request, '....html', {
'blog_nums': blog_nums,
'category_nums ': category_nums ,
'tag_nums ': tag_nums ,
})
但是如果这样的话,我们需要在每一个页面的试图函数中添加上述语句,这样一来增加了代码的重复度,二来也加剧了数据库的负担,每一个页面都要对数据库所有进行查询统计。从这两方面考虑,我们可以单独在创建一个数据表,用来记录博客、分类、标签以及主页的访问量。
新建数据表
models.py
class Counts(models.Model):
"""
统计博客、分类和标签的数目
"""
blog_nums = models.IntegerField(verbose_name='博客数目', default=0)
category_nums = models.IntegerField(verbose_name='分类数目', default=0)
tag_nums = models.IntegerField(verbose_name='标签数目', default=0)
visit_nums = models.IntegerField(verbose_name='网站访问量', default=0)
class Meta:
verbose_name = '数目统计'
verbose_name_plural = verbose_name
然后执行makemigrations
和migrate
。
修改admin.py
我们需要在后台进行数据库的写入,由于我们这个数据表只是用来统计的,因此只需要添加一个对象就行了。
from myblog.models import Counts
class CountsAdmin(admin.ModelAdmin):
list_display = ['blog_nums', 'category_nums', 'tag_nums', 'visit_nums']
admin.site.register(Counts, CountsAdmin)
在数目统计新建一个对象,此时默认的值都为0,我们将数据的统计工作在后台操作时执行,从而减轻前端页面访问时对数据库的压力。
class BlogAdmin(admin.ModelAdmin):
list_display = ['title', 'click_nums', 'category', 'create_time', 'modify_time']
def save_model(self, request, obj, form, change):
obj.save()
#统计博客数目
blog_nums = Blog.objects.count()
count_nums = Counts.objects.get(id=1)
count_nums.blog_nums = blog_nums
count_nums.save()
#博客分类数目统计
obj_category = obj.category
category_number = obj_category.blog_set.count()
obj_category.number = category_number
obj_category.save()
#博客标签数目统计
obj_tag_list = obj.tag.all()
for obj_tag in obj_tag_list:
tag_number = obj_tag.blog_set.count()
obj_tag.number = tag_number
obj_tag.save()
def delete_model(self, request, obj):
# 统计博客数目
blog_nums = Blog.objects.count()
count_nums = Counts.objects.get(id=1)
count_nums.blog_nums = blog_nums - 1
count_nums.save()
# 博客分类数目统计
obj_category = obj.category
category_number = obj_category.blog_set.count()
obj_category.number = category_number - 1
obj_category.save()
# 博客标签数目统计
obj_tag_list = obj.tag.all()
for obj_tag in obj_tag_list:
tag_number = obj_tag.blog_set.count()
obj_tag.number = tag_number - 1
obj_tag.save()
obj.delete()
class CategoryAdmin(admin.ModelAdmin):
list_display = ['name', 'number']
def save_model(self, request, obj, form, change):
obj.save()
category_nums = Category.objects.count()
count_nums = Counts.objects.get(id=1)
count_nums.category_nums = category_nums
count_nums.save()
def delete_model(self, request, obj):
obj.delete()
category_nums = Category.objects.count()
count_nums = Counts.objects.get(id=1)
count_nums.category_nums = category_nums
count_nums.save()
class TagAdmin(admin.ModelAdmin):
list_display = ['name', 'number']
def save_model(self, request, obj, form, change):
obj.save()
tag_nums = Tag.objects.count()
count_nums = Counts.objects.get(id=1)
count_nums.tag_nums = tag_nums
count_nums.save()
def delete_model(self, request, obj):
obj.delete()
tag_nums = Tag.objects.count()
count_nums = Counts.objects.get(id=1)
count_nums.tag_nums = tag_nums
count_nums.save()
这样就完成了在对博客进行添加、编辑、删除时,后台数据的统计工作了。
完善相关模板代码
# 博客、标签、分类数目统计
count_nums = Counts.objects.get(id=1)
blog_nums = count_nums.blog_nums
cate_nums = count_nums.category_nums
tag_nums = count_nums.tag_nums
return render(request, '....html', {
'blog_nums': blog_nums,
'cate_nums ': category_nums ,
'tag_nums ': tag_nums ,
})
再在模板中将对应位置的数目添加上即可:
{{ blog_nums }}
{{ cate_nums }}
{{ tag_nums }}
这样就完成了博客的统计功能。
但是在实际操作过程中,会出现如下bug:
- 在新增博客时,博客标签的数目并不会同步,需要再次保存后才可以。初步判断是因为新的博客在保存操作时,还没有写入数据库,因此查询到的标签是空的。
- 在删除博客类别或者标签时,对应的博客删除了,但是对应的统计数据并未实时更新。
留着这两个bug日后再来解决吧。
——————————————————————————————————————————
项目的完整代码:django_blog
觉得有用的欢迎给个star。