Django 个人博客搭建 (3)- 定制 admin

本贴最后更新于 2048 天前,其中的信息可能已经时移世易

一. 前言

注意

在开始教程之前,为了更合理地拆分功能模块,我把之前创建的名称为 front_blog 的 APP 改为了 front,admin_blog 改为了 article,希望小伙伴也能改一下,抱歉了。

在上一篇博文 Django 个人博客搭建(2)-编写视图 中,主要讲述了如何在 Django 中编写视图,粗略地利用 django 自带的 admin 添加了一篇文章。接下来,将讲述如何定制 admin 以及一些使用技巧。

二. 定制 admin

1. 侧边栏优化

修改模型名称

运行 Django 项目,进入 admin。发现侧边栏的 App 名称和模型名称都为英文,需要将其改为中文。

  • 修改 article/models.py,为每一个模型类添加 Meta 的 class 属性。verbose_name 表示后台界面模型显示名称,verbose_name_plural 表示复数形式名称,中文不分单复数,其值和 verbose_name 相同即可。具体代码如下:
from django.conf import settings from django.db import models # 文章模型类 class Article(models.Model): id = models.BigAutoField(primary_key=True) # 主键 user = models.ForeignKey(settings.AUTH_USER_MODEL, on_delete=models.CASCADE, verbose_name="作者") # 与自带的auth.user关联 label = models.ManyToManyField('Label', verbose_name="标签") # Label和Article为多对多关系 title = models.CharField(max_length=100, verbose_name="标题") # 标题 content = models.TextField(max_length=100000, verbose_name="内容") # 内容 summary = models.CharField(blank=True, max_length=200, verbose_name="摘要") # 摘要 gmt_created = models.DateTimeField(blank=True, null=True, auto_now_add=True) # 创建时间 gmt_modified = models.DateTimeField(blank=True, null=True, auto_now=True) # 修改时间 class Meta: verbose_name = '文章' # 后台模型显示名称 verbose_name_plural = '文章' # 后台模型复数显示名称 # 分类模型类 class Category(models.Model): id = models.BigAutoField(primary_key=True) category_name = models.CharField(max_length=32, verbose_name="分类名称") # 分类名 gmt_created = models.DateTimeField(blank=True, null=True, auto_now_add=True) # auto_now_add为添加时的时间,更新对象时不会有变动。 gmt_modified = models.DateTimeField(blank=True, null=True, auto_now=True) # auto_now无论是你添加还是修改对象,时间为你添加或者修改的时间。 class Meta: verbose_name = '分类' verbose_name_plural = '分类' # 标签模型类 class Label(models.Model): id = models.BigAutoField(primary_key=True, verbose_name="标签名称") label_name = models.CharField(max_length=32) # 标签名 category = models.ManyToManyField('Category') # Label和Category是多对多关系 gmt_created = models.DateTimeField(blank=True, null=True, auto_now_add=True) # auto_now_add为添加时的时间,更新对象时不会有变动。 gmt_modified = models.DateTimeField(blank=True, null=True, auto_now=True) # auto_now无论是你添加还是修改对象,时间为你添加或者修改的时间。 class Meta: verbose_name = '标签' verbose_name_plural = '标签'
  • 修改完之后刷新后台界面,查看具体效果。
    fabcba078cb448ada7b3b1da2c2f9f57.png

修改 App 名称

  • 修改模型显示名称之后,我们发现 app 名称仍然为英文 Article,需要将其改为中文。

  • 进入 article/init.py,设置默认 app_config,重新定义 AppConfig,加入 verbose_name 属性,verbose_name 的值即为后台 app 显示名称,如下。

from django.apps import AppConfig import os default_app_config = 'article.ArticleConfig' # 获取apps所在文件夹名字,如果文件夹名字修改,这里可以动态调整 def get_current_app_name(_file): return os.path.split(os.path.dirname(_file))[-1] class ArticleConfig(AppConfig): # 这里apps所在文件夹名字直接固定,如果更改则也需要调整 # name = 'article' name = get_current_app_name(__file__) # 这里的结果是:article verbose_name = '文章管理'
  • 修改完之后刷新后台界面,操作无误的话可以看到 APP 名称也变成中文了。
    02.png

2. 表单优化

表单字段显示优化

  • 点击文章管理/文章,然后点击之前添加的那篇文章,发现表单名称都为英文。

  • 将其修改为自定义中文字段,修改 article/models.py,为每一个字段添加 verbose_name 属性,该属性的值即为后台表单中显示的字段名称。例如我们将 Article 模型类中的 tile 字段添加属性 verbose_name="标签",则它将在后台表单中显示为 标签。代码如下。

# Create your models here. from django.conf import settings from django.db import models # 文章模型类 class Article(models.Model): id = models.BigAutoField(primary_key=True) # 主键 user = models.ForeignKey(settings.AUTH_USER_MODEL, on_delete=models.CASCADE, verbose_name="作者") # 与自带的auth.user关联 label = models.ManyToManyField('Label', verbose_name="标签") # Label和Article为多对多关系 title = models.CharField(max_length=100, verbose_name="标题") # 标题 content = models.TextField(max_length=100000, verbose_name="内容") # 内容 summary = models.CharField(blank=True, max_length=200, verbose_name="摘要") # 摘要 gmt_created = models.DateTimeField(blank=True, null=True, auto_now_add=True) # 创建时间 gmt_modified = models.DateTimeField(blank=True, null=True, auto_now=True) # 修改时间 class Meta: verbose_name = '文章' verbose_name_plural = '文章' # 分类模型类 class Category(models.Model): id = models.BigAutoField(primary_key=True) category_name = models.CharField(max_length=32, verbose_name="分类名称") # 分类名 gmt_created = models.DateTimeField(blank=True, null=True, auto_now_add=True) # auto_now_add为添加时的时间,更新对象时不会有变动。 gmt_modified = models.DateTimeField(blank=True, null=True, auto_now=True) # auto_now无论是你添加还是修改对象,时间为你添加或者修改的时间。 class Meta: verbose_name = '分类' verbose_name_plural = '分类' # 标签模型类 class Label(models.Model): id = models.BigAutoField(primary_key=True, verbose_name="标签名称") label_name = models.CharField(max_length=32) # 标签名 category = models.ManyToManyField('Category') # Label和Category是多对多关系 gmt_created = models.DateTimeField(blank=True, null=True, auto_now_add=True) # auto_now_add为添加时的时间,更新对象时不会有变动。 gmt_modified = models.DateTimeField(blank=True, null=True, auto_now=True) # auto_now无论是你添加还是修改对象,时间为你添加或者修改的时间。 class Meta: verbose_name = '标签' verbose_name_plural = '标签'
  • 点击文章列表中的文章,进入修改页面,检验修改效果。
    03.png

列表字段显示优化

之前我们在 artilce/admin.py 中利用了 admin.site.register 注册模型类,但这只能够简单地对数据进行管理。

from django.contrib import admin # 导入模型类 from article.models import Article, Category, Label # 注册 admin.site.register(Article) admin.site.register(Category) admin.site.register(Label)

文章列表并不能显示标题和作者等信息。因此我们需要借助 Django 为我们提供的 ModelAdmin 进行深度定制,ModelAdmin 类是一个可以继承的基类,它负责 admin 页面里的数据展示。

  • 修改 artilce/admin.py,新建 ArticleAdmin 类,在其中写入 list_displaylist_display 的值是一个元祖,它表明哪些字段将在列表中显示。例如,将 ArticleAdmin 中的 list_display 值设为 ('title', 'user', 'gmt_created'),如下:

    注意:不要忘记把 Article 类和 ArticleAdmin 类通过 admin.site.register(Article, ArticleAdmin) 注册到 admin 站点中

from django.contrib import admin # 导入模型类 from article.models import Article, Category, Label class ArticleAdmin(admin.ModelAdmin): list_display = ('title', 'user', 'gmt_created') # 注册 admin.site.register(Article, ArticleAdmin) admin.site.register(Category) admin.site.register(Label)
  • 刷新后台界面,查看文章列表,观察效果。
    04.png

列表多对多属性显示

那如果我们想在列表中显示多对多字段属性该怎么办,例如,在文章列表中,想要显示标签属性(文章标签ManyToMany 多对多关系)

  • 显示多对多关系字段,需要重新定义显示函数,利用数据库 ORM 方法返回关联的对象中所需要显示的字段。

  • 修改 artilce/admin.py,在 list_display 中加入自定义字段 标签,定义并实现 标签 函数,如下。

    注意:自定义字段名称与函数名称要一致

from django.contrib import admin # 导入模型类 from article.models import Article, Category, Label class ArticleAdmin(admin.ModelAdmin): # 显示的字段 list_display = ('title', 'user', '标签', 'gmt_created') # 定义标签显示 def 标签(self, obj): return [l.label_name for l in obj.label.all()] # 返回与Article关联的Label的label_name字段属性的值 filter_horizontal = ('label',) # 表示对label属性进行过滤 # 注册 admin.site.register(Article, ArticleAdmin) admin.site.register(Category) admin.site.register(Label)
  • 刷新后台界面,检查修改结果。
    08.png

表单多对多字段显示

  • 进入添加标签页面,我们发现分类显示并未显示分类名称。
    05.png

  • 为了能够显示分类名称,需要修改 article/models.py 文件,在 Category 模型类中重写 __str__ 方法,返回分类名称 category_name 属性。同时为了能在添加文章时显示标签名称,也在 Lable 模型类中重写 __str__ 方法。具体代码如下:

from django.conf import settings from django.db import models # 文章模型类 class Article(models.Model): id = models.BigAutoField(primary_key=True) # 主键 user = models.ForeignKey(settings.AUTH_USER_MODEL, on_delete=models.CASCADE, verbose_name="作者") # 与自带的auth.user关联 label = models.ManyToManyField('Label', verbose_name="标签") # Label和Article为多对多关系 title = models.CharField(max_length=100, verbose_name="标题") # 标题 content = models.TextField(max_length=100000, verbose_name="内容") # 内容 summary = models.CharField(blank=True, max_length=200, verbose_name="摘要") # 摘要 gmt_created = models.DateTimeField(blank=True, null=True, auto_now_add=True) # 创建时间 gmt_modified = models.DateTimeField(blank=True, null=True, auto_now=True) # 修改时间 class Meta: verbose_name = '文章' verbose_name_plural = '文章' def __str__(self): return self.title # 分类模型类 class Category(models.Model): id = models.BigAutoField(primary_key=True) category_name = models.CharField(max_length=32, verbose_name="分类名称") # 分类名 gmt_created = models.DateTimeField(blank=True, null=True, auto_now_add=True) # auto_now_add为添加时的时间,更新对象时不会有变动。 gmt_modified = models.DateTimeField(blank=True, null=True, auto_now=True) # auto_now无论是你添加还是修改对象,时间为你添加或者修改的时间。 class Meta: verbose_name = '分类' verbose_name_plural = '分类' def __str__(self): return self.category_name # 在后台表单中显示分类名 # 标签模型类 class Label(models.Model): id = models.BigAutoField(primary_key=True) label_name = models.CharField(max_length=32, verbose_name="标签名称") # 标签名 category = models.ManyToManyField('Category', verbose_name="分类") # Label和Category是多对多关系 gmt_created = models.DateTimeField(blank=True, null=True, auto_now_add=True) # auto_now_add为添加时的时间,更新对象时不会有变动。 gmt_modified = models.DateTimeField(blank=True, null=True, auto_now=True) # auto_now无论是你添加还是修改对象,时间为你添加或者修改的时间。 class Meta: verbose_name = '标签' verbose_name_plural = '标签' def __str__(self): return self.label_name
  • 刷新后台页面,进入添加标签页面,不出意外就能显示出分类名称了。
    06.png

3. 常用功能集成

添加搜索栏和分页

后台中我们有时候需要查询参数,默认是没有开启搜索功能的,我们需要在 article/admin.py 中加入 search_fields = ('title', 'label__label_name') 来开启搜索功能。

search_fields 中的参数是模型类中的字段名,该字段名可以用来进行关键字查询。跨表查询类似于 django 的数据库 ORM 关系,在这里先不细说。

想要了解 Django 自带的 ORM 数据库 API 的可以查看我的另外一篇博客 Django 数据库常用 ORM 方法

同时加入分页参数 list_per_page,即每页显示条数。具体代码如下:

from django.contrib import admin # 导入模型类 from article.models import Article, Category, Label class ArticleAdmin(admin.ModelAdmin): # 显示的字段 list_display = ('title', 'user', 'show_labels', 'gmt_created', 'gmt_modified') # 定义标签显示 def show_labels(self, obj): return [l.label_name for l in obj.label.all()] # 返回与Article关联的Label的label_name字段属性的值 show_labels.short_description = "标签" filter_horizontal = ('label',) # 表示对label属性进行过滤 search_fields = ('title', 'label__label_name') # 可搜索属性 list_per_page = 10 # 每页条数 class LabelAdmin(admin.ModelAdmin): list_display = ('label_name', 'show_categories', 'gmt_created', 'gmt_modified') # 显示的字段 def show_categories(self, obj): return [c.category_name for c in obj.category.all()] show_categories.short_description = "分类" filter_horizontal = ('category',) # 表示对label属性进行过滤 search_fields = ('label_name', 'category__category_name') # 可搜索属性 list_per_page = 10 class CategoryAdmin(admin.ModelAdmin): # 显示的字段 list_display = ('category_name', 'gmt_created', 'gmt_modified') list_per_page = 10 # 注册 admin.site.register(Article, ArticleAdmin) admin.site.register(Category, CategoryAdmin) admin.site.register(Label, LabelAdmin)
  • 修改完之后,刷新后台界面,测试搜索功能。
    07.png

Django 自带的 admin 还有很多强大的功能,在这里不再一一叙述了,小伙伴们可以自行钻研一波。下一篇将讲述如何编辑博客主页视图和页面显示。

  • Django
    47 引用 • 72 回帖 • 4 关注
  • Python

    Python 是一种面向对象、直译式电脑编程语言,具有近二十年的发展历史,成熟且稳定。它包含了一组完善而且容易理解的标准库,能够轻松完成很多常见的任务。它的语法简捷和清晰,尽量使用无异义的英语单词,与其它大多数程序设计语言使用大括号不一样,它使用缩进来定义语句块。

    556 引用 • 675 回帖
  • 博客

    记录并分享人生的经历。

    273 引用 • 2388 回帖 • 1 关注

相关帖子

欢迎来到这里!

我们正在构建一个小众社区,大家在这里相互信任,以平等 • 自由 • 奔放的价值观进行分享交流。最终,希望大家能够找到与自己志同道合的伙伴,共同成长。

注册 关于
请输入回帖内容 ...