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

栏目: Python · 发布时间: 5年前

内容简介:“标签”是作者从文章中提取的好在标签功能也有优秀的三方库:首先在

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

好在标签功能也有优秀的三方库: 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>
...

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

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

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

列表中显示标签

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

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

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

templates/article/list.html

...
<!-- 栏目 -->
...

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

...

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

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

刷新列表页面看看效果:

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

标签过滤

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

与搜索功能一样,只需要调取数据时用 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 用方括号包起来。

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 }}&search={{ search }}&column={{ column }}&tag={{ tag }}" class="btn btn-success">
    « 1
</a>

<!-- 上面3条是举例,其他类似地方也请补充进去 -->
...

标签过滤功能就完成了。

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

总结

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

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

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

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

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


以上所述就是小编给大家介绍的《Django搭建个人博客:文章标签功能》,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对 码农网 的支持!

查看所有标签

猜你喜欢:

本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们

HotSpot实战

HotSpot实战

陈涛 / 人民邮电出版社 / 2014-3 / 69

《HotSpot实战》深入浅出地讲解了HotSpot虚拟机的工作原理,将隐藏在它内部的本质内容逐一呈现在读者面前,包括OpenJDK与HotSpot项目、编译和调试HotSpot的方法、HotSpot内核结构、Launcher、OOP-Klass对象表示系统、链接、运行时数据区、方法区、常量池和常量池Cache、Perf Data、Crash分析方法、转储分析方法、垃圾收集器的设计演进、CMS和G......一起来看看 《HotSpot实战》 这本书的介绍吧!

HTML 压缩/解压工具
HTML 压缩/解压工具

在线压缩/解压 HTML 代码

MD5 加密
MD5 加密

MD5 加密工具

Markdown 在线编辑器
Markdown 在线编辑器

Markdown 在线编辑器