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

好在标签功能也有优秀的三方库: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...
<!-- 提交文章的表单 -->
<form method="post" action=".">...<!-- 文章标签 --><div class="form-group"><label for="tags">标签</label><input type="text" class="form-control col-3" id="tags" name="tags"></div>...
</form>
...

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

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

列表中显示标签

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

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

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

templates/article/list.html...
<!-- 栏目 -->
...<!-- 标签 -->
<span>{% for tag in article.tags.all %}<a href="#"class="badge badge-secondary" >{{ tag }}</a>{% endfor %}
</span>...

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

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

刷新列表页面看看效果:

标签过滤

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

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

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

templates/article/list.html...<!-- 标签 -->
<span>{% for tag in article.tags.all %}<a href="{% url 'article:article_list' %}?tag={{ tag }}"class="badge badge-secondary" >{{ tag }}</a>{% endfor %}
</span>...

然后在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...<!-- 所有类似地方加上 tag 参数,如排序、翻页等 --><a href="{% url 'article:article_list' %}?search={{ search }}&column={{ column }}&tag={{ tag }}">最新
</a>...<a href="{% url 'article:article_list' %}?order=total_views&search={{ search }}&column={{ column }}&tag={{ tag }}">最热
</a>...<a href="?page=1&order={{ order }}&search={{ search }}&column={{ column }}&tag={{ tag }}" class="btn btn-success">&laquo; 1
</a><!-- 上面3条是举例,其他类似地方也请补充进去 -->
...

标签过滤功能就完成了。

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

总结

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

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

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

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

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


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

Django搭建个人博客:文章标签功能相关推荐

  1. Django搭建个人博客:用django-notifications实现消息通知

    凭借你勤奋的写作,拜读你文章的用户越来越多,他们的评论也分散在众多的文章之中.作为博主,读者的留言肯定是要都看的:而读者给你留言,自然也希望得到回复. 怎么将未读的留言呈现给正确的用户呢?总不能用户自 ...

  2. Django搭建简易博客

    Django简易博客,主要实现了以下功能 连接数据库 创建超级用户与后台管理 利用django-admin-bootstrap美化界面 template,view与动态URL 多说评论功能 Markd ...

  3. 10分钟利用django搭建一个博客

    以前老是听说ROR开发有多快多块,网上还有朋友为了证明这,专门制作了10分钟利用rails框架搭建一个简易博客的教程,最近学习django框架,觉得django给开发者的便捷也很多,心血来潮来写个10 ...

  4. 基于Hexo框架快速搭建个人博客--文章一键发布(五)

    基于Hexo框架快速搭建个人博客--文章一键发布 一.文章对比 二.发布到Github 三.一键发布 四.总结 博客链接: 会思想的苇草i 文章链接: 基于Hexo框架快速搭建个人博客–搭建(一) 基 ...

  5. Django搭建个人博客:用户的登录和登出

    用户管理 用户数据可以说是大部分网站最重要的资产.用户管理就是对用户数据进行增删改查等操作的功能,自然也就非常的重要了. 本章开始学习用户管理的内容,首先从用户登录开始. 在Django中用app来区 ...

  6. 基于hexo框架快速从0到1搭建个人博客----文章写作(四)

    基于hexo框架快速从0到1搭建个人博客----文章写作 一.Github图床(图片存储) 二.PicGo(图片上传) 三.jsDelivr(CDN加速) 四.Typora(写文传图) 五.总结 一. ...

  7. 新手学习——用django搭建个人博客_day2

    一.模型设计 任何一个产品,最开始应该就是设计数据模型,模型设计好一般就不会轻易去修改它了,但是在此处,我们暂时不考虑用户登录评论这些,只考虑博客展示需要的模型.对应的表应该为以下: 博客:标题 作者 ...

  8. Django搭建个人博客Blog-Day05

    创建文章模块 创建文章app 在虚拟环境中,apps路径下使用如下代码: # 进入虚拟环境 workon wsl # 进入要创建app的路径下 cd blog/blog/apps # 创建app py ...

  9. 用django搭建个人博客(一)

    用django2.0搭建个人博客 博客网站的需求与规划 该个人博客为简单的入门示范网站,具有以下功能 项目名称为mblog 通过admin管理界面发帖.编辑以及删除贴文,且此界面支持markdown语 ...

  10. Django搭建个人博客:用户的注册

    既然有登录登出,那么用户的注册肯定也是少不了的. 注册表单类 用户注册时会用到表单来提交账号.密码等数据,所以需要写注册用的表单/userprofile/forms.py: /userprofile/ ...

最新文章

  1. 为什么使用单页应用_为什么我讨厌您的单页应用
  2. 2016网络安全***赛记录
  3. Scala闭包特性的一个测试
  4. python中urframe函数的用法_python类中的内置函数
  5. 编译后没有taget文件夹_matconvnet安装、编译、配置
  6. 跳转语句_javascript流程语句(单分支)
  7. 个人知识库的分类目录_搭建个人知识体系,让印象笔记成为我们的“第二大脑”!...
  8. 打包巨慢怎么办?这些工具让你爱不释手
  9. python apkg,Python 自动加固APK
  10. [从零开始学习FPGA编程-49]:视野篇 - 芯片是如何被设计出来的?
  11. leetcode402. 移掉 K 位数字
  12. linux 路由 pppoe ipv6,ubuntu PPPoE v6 Server配置
  13. SATA、mSATA、M.2、M.2(NVMe)、PCIE固态硬盘接口详解
  14. android 电视 网上邻居,手机要怎么连接安卓智能电视或电视盒子
  15. 全球与中国农用软管卷盘市场现状及未来发展趋势
  16. 《“桥板灯”的来历》——游城“明经胡氏”
  17. scrapy crawl爬取我爱我家二手房的数据
  18. 304、bootstrap 之 图片样式
  19. 阿里云服务器远程连接
  20. 【关于c++中或逻辑运算法||执行顺序问题】

热门文章

  1. android标签打印,Android TSC热敏标签打印机打印
  2. php mysql子查询,mysql子查询命令
  3. android wifi在待机状态下可用,Android APP休眠状态下无法联网和播放音频解决方案...
  4. MapReduce会自动忽略文件夹下的.开头的文件
  5. Python入门系列(1):如何使用Sublime text开发Python
  6. 蓝桥杯历届试题 地宫取宝 dp or 记忆化搜索
  7. BZOJ-1922 大陆争霸 多限制、分层图最短路 (堆+dijkstra)
  8. hdu 2363(最短路+枚举)
  9. Java-WAS的Hello world
  10. Java零基础入门 :(1) windows7 配置Java环境变量