博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
Django搭建个人博客:文章标签功能
阅读量:6284 次
发布时间:2019-06-22

本文共 3800 字,大约阅读时间需要 12 分钟。

“标签”是作者从文章中提取的核心词汇,其他用户可以通过标签快速了解文章的关注点。每一篇文章的标签可能都不一样,并且还可能拥有多个标签,这是与栏目功能不同的。

好在标签功能也有优秀的三方库:,省得自己动手设计了。快速开发就是这样,能“借用”就不要自己重复劳动。

安装及设置

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

pip install django-taggit

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

my_blog/settings.py...INSTALLED_APPS = [    ...    'taggit',]...

修改文章模型

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

需要注意的是标签引用的不是内置字段,而是库中的TaggableManager,它是处理多对多关系的管理器:

article/models.py...# Django-taggitfrom 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...
...
...
...

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

多个标签最好用英文逗号进行分隔。中文逗号有的版本会报错,干脆就不要去使用了。

列表中显示标签

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

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

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

templates/article/list.html...
...
{% for tag in article.tags.all %} {
{ tag }}
{% endfor %}
...

链接中的class中是Bootstrap定义的。

插入位置紧靠在栏目按钮的后面。当然你想放到其他位置也是完全可以的。

刷新列表页面看看效果:

标签过滤

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

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

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

templates/article/list.html...
{% for tag in article.tags.all %} {
{ 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字段中过滤nametag的数据条目。赋值的字符串tag用方括号包起来。

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

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

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

templates/article/list.html...
最新... 最热... « 1
...

标签过滤功能就完成了。

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

总结

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

在学习阶段,你可以不借助他人的轮子,自己实现功能:瞎折腾对掌握基础有很大帮助。

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

  • 浅层需求某项通用功能,开发完成后改动不大:此类功能建议尽量使用轮子,加快开发效率。人生苦短,能节约的时间,一秒钟都不要浪费。
  • 需要大量定制化的功能,开发完成后需要频繁改动:此类功能因为经常对底层代码进行改动,与其在别人的代码上修修补补,还不如自己从头写了。自己的代码不仅熟悉,而且都是为定制化而生的。

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


  • 有疑问请在留言,我会尽快回复。
  • 或Email私信我:dusaiphoto@foxmail.com
  • 项目完整代码:

转载地址:http://azvpa.baihongyu.com/

你可能感兴趣的文章
linux学习笔记一----------文件相关操作
查看>>
Mono for Android 优势与劣势
查看>>
服务器端开发技术
查看>>
Python3中urllib详细使用方法(header,代理,超时,认证,异常处理)
查看>>
ajax提交多个对象,使用序列化表单和FormData
查看>>
深入分析由前序和中序重构二叉树问题
查看>>
leetcode 题解 || Valid Parentheses 问题
查看>>
将图片转成base64字符串并在JSP页面显示的Java代码
查看>>
什么是WeakHashMap--转
查看>>
js 面试题
查看>>
第二十二节,三元运算
查看>>
Yacc 与 Lex 快速入门
查看>>
Unity中HDR外发光的使用
查看>>
Flume负载均衡配置
查看>>
Ajax详解
查看>>
Ubuntu C/C++开发环境的安装和配置
查看>>
百世汇通快递地区选择插件,单独剥离
查看>>
Linux系统调用---同步IO: sync、fsync与fdatasync【转】
查看>>
【MyBatis学习06】输入映射和输出映射
查看>>
[LeetCode] Decode String 解码字符串
查看>>