Wolf从零学编程-用Django撸个Blog(五)

本文详细介绍了如何在Django框架中实现博客的分类和标签功能,包括模型设计、视图编写及URL配置等步骤。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

真是活久见,玩了两天DES,今天想把详情页不能写中文的问题解决~~把detail.html代码里的首页改成中文,它喵的居然直接就好了。既然这样,我只能继续了。

前端可能要留在最后,目前逐渐扩展功能,这次把标签和分类整进去:

mark

优快云中,分类是作者此分类下的文章汇总,标签是全站有此标签的文章汇总。我搭的是个人博客,自然两者都是作者文章汇总。

一、分类和标签的模型

每篇文章只有一个分类,一个分类下有很多文章,所以文章和分类是多对一关系;每篇文章可以有多个标签,因此文章和标签是多对多关系。分析他们关系是因为在编写模型中要用。

这是套路了,博客毕竟是数据库驱动的WEB,任何新东西都应该是从数据库开始的。

分类的模型之前写过,只有简单的几行代码:

#创建分类模型		
class Category(models.Model):
    category = models.CharField('分类',max_length=10)
	
    def __str__(self):
	    return self.category

同理,标签的模型抄写之:

#创建标签模型		
class Tag(models.Model):
    tag = models.CharField('标签',max_length=15)
	
    def __str__(self):
	    return self.tag

前面分析的多对多关系要用在Article模型中,把文章和标签的关系建立起来:

# models.py

class Article(models.Model):
    ……
    tag = models.ManyToManyField('Tag',verbose_name='标签',blank=True)
    ……

模型就这么简单,记得每次更改了数据库都要做的事:

D:\myblog>python manage.py makemigrations blog
D:\myblog>python manage.py migrate

ForeignKey和ManyToManyField的更多内容:官方文档中文文档

因为涉及一个新的模型,要把它激活才可以在后台操作。

# admin.py

from django.contrib import admin
from .models import Article,Category,**Tag**

admin.site.register(Article)
admin.site.register(Category)
**admin.site.register(Tag)**

现在我重启服务器,进入后台。

mark

Tag已经出现,可以添加一些标签。

二、分类和标签的视图

简单改了一下首页的html:

# index.html

<html>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<head><title>首页</title></head>
<body>
<h3>分类<h3>
{% for category in category_list%}
    <a href="{% url 'blog:category' category.pk %}">{{category.category}}</a><br>
{% endfor %}
<h3>标签</h3>
{% for tag in tag_list%}
    <a href="{% url 'blog:tag' tag.pk %}">{{tag.tag}}</a><br>
{% endfor %}
<h3>文章列表</h3>
{% for article in article_list%}
    <a href="{% url 'blog:detail' article.pk %}">{{article.title}}</a><br>
{% endfor %}
</body>
</html>

我的愿望是美好的,可惜现实是残酷的,此时的首页是这样的:

mark

分类和标签列表并没有显示,因为我的首页视图里并没有对他们的操作,现在重写一个方法,返回分类和标签的列表。

# views.py

from .models import Article,**Category,Tag**

class IndexView(ListView):
    ……
    
    #重写ListView下的get_context_data()方法,返回分类和标签列表
    def get_context_data(self,**kwargs):
        #category_list与html中一致,category与Category模型中的category一致
        kwargs['category_list'] = Category.objects.all().order_by('category')
        kwargs['tag_list'] = Tag.objects.all().order_by('tag')
        return super(IndexView,self).get_context_data(**kwargs)

一切正常的话,首页应该OK了。而我刷新首页,得到的却是这个:

mark

看到这图我就崩溃了,因为快到晚饭时间了,而django让我把分类和标签的url和view都搞定,才给显示首页。

按照习惯,先写URLconf,都照article的改写。

# blog/urls.py

urlpatterns = [
    ……
    url(r'^category/(?P<category_id>\d+)$',views.CategoryView.as_view(),name='category'),
    url(r'^tag/(?P<tag_id>\d+)$',views.TagView.as_view(),name='tag'),
]

编写分类和标签视图,因为他们的模式都是文章列表,和首页挺像,也可以模仿着改。

# views.py

class CategoryView(ListView):
    template_name = 'blog/index.html'  #和首页一样
    context_object_name = 'article_list'  #要的就是文章列表,也是一样

	#重写get_queryset方法,从已发布的文章中按分类筛选
    def get_queryset(self):
	    article_list = Article.objects.filter(category=self.kwargs['category_id'],status='published')
	    return article_list
    
    #重写,返回分类和标签列表
    def get_context_data(self,**kwargs):
        kwargs['category_list'] = Category.objects.all().order_by('category')
        kwargs['tag_list'] = Tag.objects.all().order_by('tag')
        return super(CategoryView,self).get_context_data(**kwargs)
        
#和CategoryView完全一样        
class TagView(ListView):
    template_name = 'blog/index.html'  #和首页一样
    context_object_name = 'article_list'  #要的就是文章列表,也是一样

	#重写get_queryset方法,从已发布的文章中按标签筛选
    def get_queryset(self):
	    article_list = Article.objects.filter(tag=self.kwargs['tag_id'],status='published')
	    return article_list
    
    #重写,返回分类和标签列表
    def get_context_data(self,**kwargs):
        kwargs['category_list'] = Category.objects.all().order_by('category')
        kwargs['tag_list'] = Tag.objects.all().order_by('tag')
        return super(TagView,self).get_context_data(**kwargs)

大功告成,请看效果:

mark

写完我自己有个疑问:这分类和标签简直一模一样,为什么要分成2个功能?

开饭前茅塞顿开!分类是多对一,标签是多对多,就冲这一点,我就要分开写啊~~现在看首页貌似一样,未来专攻前端时自然会把他俩区分开的。

Done!下次添加评论。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值