1、创建标签页面
与上一节中创建归档页面一样,这里就不再赘述了,直接给出程序代码。
tags.html
{% extends 'base.html' %}
{% block title %}
标签云
{% endblock %}
{% block title %}
<div class="content-wrap">
...
{% for tag in all_tag %}
<a href="http://www.geerniya.cn/tags/django/" style="font-size: 12.5px; color: #999">{{ tag.name }}</a>
{% endfor %}
...
{% endblock %}
view.py
class TagView(View):
def get(self, request):
all_tag = Tag.objects.all()
return render(request, 'tags.html', {
'all_tag': all_tag,
})
url.py
url(r'^tags/$', TagView.as_view(), name='tags'),
这些都是很常规的做法,完成后,显示效果如下所示:
我们可以看出,标签确实排列出来了,但是没有什么显示效果。如果我们想按照标签下面的博客数目的多少进行展示
2、实现不同大小的标签云样式
为了实现上述效果, 我们首先应当统计得到每一个标签下的博客数量。我们知道Tag与Blog是多对多的关系,那么在我们知道某一个具体的tag时,可以通过tag.blog_set.count
语句得到该标签在的博客数量。
我这里能想到的是比较笨的判断方法,也就是if语句,对于不同的博客数目,给定不同的展示效果,如下:
{% for tag in all_tag %}
<a href="{% url 'tag_name' tag.name %}"
{% if tag.blog_set.count <= 2 %}
style="font-size: 12.5px; color: #999"
{% elif tag.blog_set.count <= 5 %}
style="font-size: 15px; color: #666"
{% elif tag.blog_set.count <= 10 %}
style="font-size: 20px; color: #444"
{% elif tag.blog_set.count <= 20 %}
style="font-size: 25px; color: #222"
{% elif tag.blog_set.count <= 50 %}
style="font-size: 30px; color: #111"
{% else %}
style="font-size: 35px; color: #000"
{% endif %}>
{{ tag.name }}</a>
{% endfor %}
根据不同个博客数量,显示出不同的文字大小和颜色样式,一堆if语句,确实显得很傻,如果各位有其它好的想法,欢迎在下面给我评论下。
3、数据库的改进
采用tag.blog_set.count
确实可以得到想要的结果,但是如果有100个标签,那就要对blog数据表进行100次查询统计,感觉对数据库压力还挺大的,我们可以对其进行适当的优化。我们的tag表单之前只设置了一个字段name
, 现在我们可以给它增加一个number
字段, 用来记录改标签下博客的数量。当然,Category
表也可以增加这个字段。
修改models.py
class Category(models.Model):
name = models.CharField(verbose_name='博客类别', max_length=20)
number = models.IntegerField(verbose_name='分类数目', default=1)
...
class Tag(models.Model):
name = models.CharField(verbose_name='博客标签', max_length=20)
number = models.IntegerField(verbose_name='标签数目', default=1)
...
增加字段后,切记不要忘了执行如下操作, 将新增的字段写入到数据库中:
makemigrations
migrate
修改admin.py
现在标签与分类的number都是默认值0,我们怎么才能将其添加进来呢。我们当然希望是在后台自动添加,也就是在我们新增博客时自动统计标签与分类的数目。这可以在admin.py中实现:
class BlogAdmin(admin.ModelAdmin):
list_display = ['title', 'click_nums', 'category', 'create_time', 'modify_time']
def save_model(self, request, obj, form, change):
obj.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()
这里我们在BlogAdmin中重写了save_model方法,在里面定义了保存博客时将该博客的分类数与标签数分别添加到对应的表中。让然,我们还应当再重写一个delete_model方法,具体的代码跟上面是一样的,这里就不再写了。
这样之后,我们应当将我们之前tags.html中的tag.blog_set.count
修改为tag.number
即可。
——————————————————————————————————————————