137-使用django实现分类功能,基于django 3.0的最新特性
2020-09-08 17:17 lzhshn 阅读(811) 评论(0) 编辑 收藏 举报学习python web编程直接使用了最新的版本,python 3.8和django 3.0,默认安装都是最新版本。
以下是我用django实现的分类功能。功能主体已经实现,但是在admin后台和模板中的编辑页面,分类显示英文的value而不是中文lable,但是在最终渲染之后显示时,都显示lable。
不知道有谁知道如何在admin和模板里,都显示中文的label???
【1】关于TextChoices
我们自己定义的分类Category基于TextChoices,写法为:value = label,可以有多个label,需要加上引号,并且用逗号分开。
1 2 3 4 5 6 7 8 | class Category(models.TextChoices): UNKNOWN = '默认' CULTURE = '文化' SCIENCE = '科技' NATURAL = '自然' EMOTION = '情感' LIFE = '生活' WORK = '工作' |
【2】将定义的分类使用到其他模型中
注意这条:
1 | note_category = models.CharField(max_length = 64 , choices = Category.choices, default = Category.UNKNOWN) |
使用choices进行关联,并且指定了默认值。之后,使用note.note_category即可获得其分类。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 | class MyNote(models.Model): user = models.ForeignKey(User, on_delete = models.CASCADE) author = models.CharField(max_length = 64 ) title = models.CharField(max_length = 64 , default = 'a default title' ) note_category = models.CharField(max_length = 64 , choices = Category.choices, default = Category.UNKNOWN) content = RichTextField(config_name = 'awesome_ckeditor' ) pub_time = models.DateTimeField(auto_now_add = True ) pub_date = models.DateField(auto_now_add = True ) update_time = models.DateTimeField(auto_now = True ) praise_count = models.BigIntegerField(default = 0 ) collect_count = models.BigIntegerField(default = 0 ) comment_num = models.BigIntegerField(default = 0 ) hot_index = models.BigIntegerField(default = 0 ) open_bool = models.BooleanField(default = True ) personal_tags = TaggableManager() def __str__( self ): return self .title[ 0 : 32 ] |
【3】分类是一级菜单。我们设定点击分类后进入到分类页面,并且默认打开的是“默认”分类。
这里特别要注意,由于首页被很多其他页面作为母模板,如果你尝试在首页的{% url %}里使用一个变量作为值,则必须要在所有继承或者次级继承的模板里,都要在上下文里传入相关值,这种做法可以说是个死穴!
因此可以看到,这里有些链接直接带有一些常量值。当然:常量并不是随意写的,是一系列参数中的一个“可确认”的值。
1 2 3 4 5 6 7 8 | < div id="menu"> < span class="menu_item">< a href="{% url 'notebook:start_page' %}">首页</ a ></ span > < span class="menu_item">< a href="{% url 'notebook:category' '默认' %}">分类</ a ></ span > < span class="menu_item">< a href="{% url 'notebook:my_notes' 1 %}">我的</ a ></ span > < span class="menu_item">< a href="{% url 'notebook:add_note' %}">新增</ a ></ span > < span class="menu_item">< a href="{% url 'notebook:all_clt' 1 %}">收藏</ a ></ span > < span class="menu_item">< a href="{% url 'notebook:add_note' %}">消息</ a ></ span > </ div > |
【4】处理分类页面的函数
函数接收一个分类值,比如从“分类”点进来,以及切换分类菜单的操作,都会传来一个分类值。
cg里面其实都是‘默认’、‘工作’这种字符串,也就是lable!
为什么用lable来传值,而不是value传值?请看:cg_open_note = MyNote.objects.filter(open_bool=True, note_category=cg).order_by('-pub_time')
这里note_category=cg,就是Category定义时的写法,前面提到过:value = label
这里通过两个过滤,将公开的,并且属于这个分类的文章,全部保存下来。
1 2 3 4 5 | @login_required def category(request, cg): cg_open_note = MyNote.objects. filter (open_bool = True , note_category = cg).order_by( '-pub_time' ) context = { 'cg_open_note' : cg_open_note, 'Category' : Category} return render(request, 'category.html' , context) |
【5】分类模板
这里对所继承的模板的两个block部分都进行了改写,一边显示当前分类的所有文章(暂未做分页处理),另一边列举所有分类。
在django中,如果用for——in——取不到内容时,可以使用一个便捷方法{% empty %},显示替代内容。
列举所有分类的方法时直接对所定义的Category直接进行for——in——取值。
Category是一个特殊的模型类,它没有实例,也没有关联关系,也不能在admin里注册,它定义后,这个类本身即可直接使用。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 | < body > {% block content %} < div class="left"> {% for note in cg_open_note %} < h3 >< a href="{% url 'notebook:op_one_note' note.pk %}">{{note.title}}</ a ></ h3 > < p >分类:{{note.note_category}} 作者:{{note.author}} 发表:{{note.pub_time}} 更新:{{note.update_time}}</ p > {% autoescape off %} < p >{{note.content|truncatechars:1024}}</ p > {% endautoescape %} {# < p >权限:{{note.open_bool}}</ p > #} < p >{{note.personal_tags.all}}</ p > {% empty %} < p >此分类下,暂无文章。不如你来发表第一篇吧!</ p >< a href="{% url 'notebook:add_note' %}">发表新文章</ a > {% endfor %} </ div > {% endblock content %} {%block side %} < div class="right"> < h4 >所有分类</ h4 > {% for cg in Category %} < p >< a href="{% url 'notebook:category' cg %}">{{cg}}</ a ></ p > {% endfor %} </ div > {% endblock side %} </ body > |
以上就是django进行分类功能的实现。使用了最新的django 3.0特性:TextChoices!
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 如何编写易于单元测试的代码
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
· 10年+ .NET Coder 心语 ── 封装的思维:从隐藏、稳定开始理解其本质意义
· 地球OL攻略 —— 某应届生求职总结
· 提示词工程——AI应用必不可少的技术
· Open-Sora 2.0 重磅开源!
· 周边上新:园子的第一款马克杯温暖上架