好久不见。小编前段时间出差,偷了个懒,真不好意思。今天我们再来看下个Django实战小案例吧。在日常Web开发过程中对数据(比如新闻和用户)的分类是必不可少的。我们会给他们分配一个类别(Category), 这个类别可能有父类别(Parent Category),有可能还有子类别(Child Category)。今天我们将教你如何利用Django实现生成动态的分类目录,这将对开发三级或联动菜单非常有用。一个惨不忍睹的效果如下所示:
废话不多说,我们来看代码。
第一步 建立APP,设置URL
我们创建一个叫demo的项目,并利用python manage.py startapp blog创建一个名叫blog的APP,并把它加入到settings.py中INSTALLED_APP里去。另外URLs里添加blog.urls.
# demo/settings.py
urlpatterns = [
path('admin/',admin.site.urls),
path('blog/',include('blog.urls')),
]
第二步 建立模型Models
我们的
模型model设计
非常简单,只有名字name,slug和父级分类3个字段。其中ForeignKey指向了自己,这样就可以实现一层一层地添加子分类了。slug是admin后台根据name自动生成地。slug会出现到我们链接url中去。
# blog/models.py
fromdjango.dbimportmodels
classCategory(models.Model):
name = models.CharField('分类名',max_length=30,unique=True)
slug = models.SlugField('slug',max_length=40)
parent_category = models.ForeignKey('self',verbose_name="父级分类",blank=True,null=True,on_delete=models.CASCADE)
classMeta:
ordering = ['name']
verbose_name ="分类"
def__str__(self):
returnself.name
第三步 设计URL
# blog/urls.py
fromdjango.urlsimportpath,re_path
from.importviews
# namespace
app_name ='blog'
urlpatterns = [
re_path(r'^category/$',
views.CategoryListView.as_view(),name='category_list'),
re_path(r'^category/(?P[-\w]+)/$',
views.CategoryDetailView.as_view(),name='category_detail'),
]
第四步 编写视图View
我们的view也非常简单,全靠通用Django的通用视图。
# blog/views.py
第五步 编写模板
# blog/templates/blog/category_list.py
{% for category in category_list %}
{{ category.name }}
{% endfor %}
# blog/templates/blog/category_detail.py
{% if category.parent_category %}
父类别:
{{ category.parent_category.name }}
{% endif %}
当前类别:
{{ category }}
{% with category.category_set.all as categories %}
{% if categories %}
子类别:
{% for category in categories %}
{{ category.name }}
{% endfor %}
{% endif %}
{% endwith %}
注意: 上述代码中我们使用了category.parent_category来获取父类别,而使用了category.category_set.all获取的子类别。请仔细品味下我们为什么这么做。
第六步 设置admin
我们希望通过Django自带的admin添加类别,并利用prepopulated_fields自动生成slug。我们只需要在admin.py里添加如下代码。
# blog/admin.py
第七步 查看效果
打开CMD终端进入项目所在文件夹,连续输入python manage.py makemigrations,python manage.py migrate和python manage.py runserver。如果你还没有创建后台的superuser,在runserver前,请输入python manage.py createsuperuser。后台效果图如下所示:
当你在admin创建好类别后,你就可以通过访问http://127.0.0.1:8000/blog/category/查看所有类别了。点击某个类别链接,你可以看到父类别,当前类别和子类别。
第八步 如何显示同级类别?
我们已经显示了父类和所有子类,那我们如何显示同一父类下的所有类别呢?我们只需要在Category的模型里增加一个获取get_same_level_category的方法,然后在模板里使用它。
defget_same_level_category(self):
ifself.parent_category:
returnself.parent_category.category_set.all().exclude(id=self.id)
这段代码的意思是:如果有父类,就获取父类下所有的子类,自身除外。模板文件新增下面一段代码。
# blog/templates/blog/category_detail.py
{% with category.get_same_level_category as categories %}
{% if categories %}
当前同级类别:
{% for category in categories %}
{{ category }}
{% endfor %}
{% endif %}
{% endwith %}
最后整个项目的目录结构和最终效果如下图所示:
好了,今天就到这里。如果喜欢我们的文章,请关注我们。
领取专属 10元无门槛券
私享最新 技术干货