Advertisement

python搭建博客文章_Django搭建个人博客:文章标签功能

阅读量:

核心词汇来自文章的作者。其他用户可凭借标签迅速掌握文章的重点内容。一篇文通常会有独特的标签,并时常包含多个相关关键词。这个特点区别于栏目功能并不存在于此。

得益于标签功能提供的高度优化第三方库Django-taggit的存在,在项目中开发者无需自行设计标签系统

安装及设置

首先在虚拟环境中安装Django-taggit:

pip install django-taggit

安装成功后,修改项目设置以添加库:

my_blog/settings.py

...

INSTALLED_APPS = [

...

'taggit',

]

...

修改文章模型

标签是文章Model的属性,因此需要修改文章模型。

必须注意的是,在标签引用时并非使用内置字段,而是来自库中的TaggableManager对象。该对象被设计为处理复杂的多对多关系。

article/models.py

...

Django-taggit

from taggit.managers import TaggableManager

...

class ArticlePost(models.Model):

...

文章标签

tags = TaggableManager(blank=True)

...

然后记得数据迁移。

带标签文章的发表

修改文章的表单类,让其能够提交标签字段:

article/forms.py

...

class ArticlePostForm(forms.ModelForm):

class Meta:

...

fields = ('title', 'body', 'tags')

然后修改发表文章的视图,保存POST中的标签:

article/views.py

...

def article_create(request):

已有代码

if request.method == "POST":

article_post_form = ArticlePostForm(data=request.POST)

if article_post_form.is_valid():

new_article = article_post_form.save(commit=False)

...

new_article.save()

新增代码,保存 tags 的多对多关系

article_post_form.save_m2m()

...

特别需要注意的是,在表单设置为commit=False选项的情况下,则必须确保通过调用save_m2m()来正确保存标签,并与传统的双向多对多关系处理方式相似。

最后就是在发表文章的模板中添加标签的表单项了:

templates/article/create.html

...

...

标签

class="form-control col-3"

id="tags"

name="tags"

...

...

运行服务器,就可以在发表页面看到效果了:

92a93e8ba4e79be18a3a7b72a8d7fb39.png

建议将多个标签以英文逗号的形式分隔开来;对于使用中文逗号的版本而言,在某些情况下可能会导致错误信息显示不出来;因此建议避免使用中文逗号来标注标签

列表中显示标签

虽然保存标签的功能已经实现了,还得把它显示出来才行。

显示标签最常用的位置是在文章列表中,方便用户筛选感兴趣的文章。

修改文章列表的模板,将标签显示出来:

templates/article/list.html

...

...

{% for tag in article.tags.all %}

class="badge badge-secondary"

{{ tag }}

{% endfor %}

...

链接中的class中是Bootstrap定义的徽章样式。

栏目按钮是插入位置的邻近项;当然你可以将其放置在其他地方。

刷新列表页面看看效果:

15937e8cb6f8a46b54657bc2e60d0013.png

标签过滤

有时候用户想搜索带有某一个标签的所有文章,现在就来做这个功能。

与搜索功能一样,只需要调取数据时用filter()方法过滤结果就可以了。

修改标签中的href,使其带有tag参数返回到View中:

templates/article/list.html

...

{% for tag in article.tags.all %}

class="badge badge-secondary"

>

{{ tag }}

{% endfor %}

...

然后在View中取得tag的值,并进行搜索。

这段代码实现了article_list()函数的全面编写(特别包含上一章末尾未涉及栏目查询的部分),以便于读者进行对比参考。

article/views.py

...

def article_list(request):

从 url 中提取查询参数

search = request.GET.get('search')

order = request.GET.get('order')

column = request.GET.get('column')

tag = request.GET.get('tag')

初始化查询集

article_list = ArticlePost.objects.all()

搜索查询集

if search:

article_list = article_list.filter(

Q(title__icontains=search) |

Q(body__icontains=search)

)

else:

search = ''

栏目查询集

if column is not None and column.isdigit():

article_list = article_list.filter(column=column)

标签查询集

if tag and tag != 'None':

article_list = article_list.filter(tags__name__in=[tag])

查询集排序

if order == 'total_views':

article_list = article_list.order_by('-total_views')

paginator = Paginator(article_list, 3)

page = request.GET.get('page')

articles = paginator.get_page(page)

需要传递给模板(templates)的对象

context = {

'articles': articles,

'order': order,

'search': search,

'column': column,

'tag': tag,

}

return render(request, 'article/list.html', context)

...

请特别注意,在 Django-taggit 框标中标签过滤的方式是 filter(tags__name__in=[tag])。具体而言,在 tags 字段内筛选 name 为 tag 的数据条目。将赋值给变量 tag 时需使用方括号包裹。

之所以这样写是因为Django-taggit还支持多标签的联合查询,比如:

Model.objects.filter(tags__name__in=["tag1", "tag2"])

为了实现带参数的交叉查询,还要将翻页等位置的href修改一下:

templates/article/list.html

...

最新

...

最热

...

« 1

...

标签过滤功能就完成了。

Django-taggit更多的用法请阅读官方文档:Django-taggit

总结

本章学习了使用Django-taggit来完成标签功能。

在学习阶段无需借鉴他人经验就能自主开发功能:通过摸爬滚打显著促进基础掌握。

实际开发时,又分为两种情况:

表面需求中的一项通用功能,在完成开发后带来的改动微乎其微:此类功能建议尽可能地采用模块化设计以提高开发效率。时光荏苒、稍纵即逝的碎片时间不容浪费。

项目需求中要求实现大量高度定制的功能,在投入运营后仍需不断修改。这类功能由于频繁修改底层代码容易出错,并非建议在现成的开源项目中反复修复;与其耗时耗力地逐步优化现有代码库不如直接从零开始编写。

到底如何选择,就根据你的喜欢进行斟酌了。

有疑问请在杜赛的个人网站留言,我会尽快回复。

或Email私信我:dusaiphoto@foxmail.com

全部评论 (0)

还没有任何评论哟~