137-使用django实现分类功能,基于django 3.0的最新特性
2020-09-08 17:17 lzhshn 阅读(843) 评论(0) 收藏 举报学习python web编程直接使用了最新的版本,python 3.8和django 3.0,默认安装都是最新版本。
以下是我用django实现的分类功能。功能主体已经实现,但是在admin后台和模板中的编辑页面,分类显示英文的value而不是中文lable,但是在最终渲染之后显示时,都显示lable。
不知道有谁知道如何在admin和模板里,都显示中文的label???
【1】关于TextChoices
我们自己定义的分类Category基于TextChoices,写法为:value = label,可以有多个label,需要加上引号,并且用逗号分开。
class Category(models.TextChoices):
UNKNOWN = '默认'
CULTURE = '文化'
SCIENCE = '科技'
NATURAL = '自然'
EMOTION = '情感'
LIFE = '生活'
WORK = '工作'
【2】将定义的分类使用到其他模型中
注意这条:
note_category = models.CharField(max_length=64, choices=Category.choices, default=Category.UNKNOWN)
使用choices进行关联,并且指定了默认值。之后,使用note.note_category即可获得其分类。
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 %}里使用一个变量作为值,则必须要在所有继承或者次级继承的模板里,都要在上下文里传入相关值,这种做法可以说是个死穴!
因此可以看到,这里有些链接直接带有一些常量值。当然:常量并不是随意写的,是一系列参数中的一个“可确认”的值。
<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
这里通过两个过滤,将公开的,并且属于这个分类的文章,全部保存下来。
@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里注册,它定义后,这个类本身即可直接使用。
<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!
浙公网安备 33010602011771号