Django Admin后台管理功能使用+二次开发 二  主要功能

时间:2024-03-07 12:28:55

一  使用环境

  开发系统: windows

  IDE: pycharm  

  数据库: msyql,navicat

  编程语言: python3.7  (Windows x86-64 executable installer)

  虚拟环境: virtualenvwrapper

  开发框架: Django 2.2

功能1:提供数据库管理功能

   基于admin模块,可以实现类似数据库客户端的功能,对数据进行增删改查

功能2:二次开发

   基于该模块的数据管理功能,可以二次定制一些实用的功能。

三  基本使用方法

使用 AbstractUser 重写用户表,变量用的中文,本人英文不好,我是一个小白,用中文便于自已理解,很多是自已的是理解,有不对的请指正,谢谢!

步骤1:在  app 的 models.py 文件中创建表

  1 """ A001jcxx===>基础信息模块"""
  2 # 导包规范-1.Python标准模块
  3 from django.db import models
  4 from django.contrib.auth.models import AbstractUser  # AbstractUser继承原用django中的用户原有字段再扩展
  5 # 导包规范-2.第三方模块
  6 from multiselectfield import MultiSelectField
  7 # 导包规范-3.自定义模块
  8 
  9 
 10 # 000-共公model用的字段表,模型抽象基类
 11 class BaseModel(models.Model):
 12     创建时间 = models.DateTimeField(auto_now_add=True)
 13     更新时间 = models.DateTimeField(auto_now=True)
 14     删除标记 = models.BooleanField(default=False)
 15 
 16     class Meta:  # 说明是一个抽象模型类,class Meta做为嵌套类,主要目的是给上级类添加一些功能,或者指定一些标准
 17         abstract = True  # 定义这类是不是抽象类,所谓抽象类就是在实例的时候并不会起作用,只是用来定义一些公共字段,给子类提供继承,子类是可以创建表的。
 18 
 19 
 20 # 01-用户个人信息
 21 class UserProfile(AbstractUser, BaseModel):
 22     # 必需在settings中设定,配置django认证系统使用的模型类AbstractUse,必需配置 AUTH_USER_MODEL= "APP名.模型类名"
 23     """
 24     设计字段属性:字段大小,是否必填,是否唯一。
 25     字段常用参数说明:
 26         null=True:文本类型字段(CharField,TextField)不要设置此参数,文本类数据库中默认存的是一个空字符串,并不是一个null值.
 27         blank=True:表单验证层的,不影响数据库.
 28         default:默认值,可以指定一个函数,保存前先执行函数,再将函数值保存到数据库中.(例:default=now).
 29             default=\'\' 相当于 blank=True, null=True,两者具有相同的结果
 30         db_column:改变映射到数据库存中模型字段名.
 31         primary_key=True:主键.
 32         unique:字段值设为唯一,一般邮箱/手机号码.
 33 
 34     Meta设置
 35         db_table:模型映射到数据库中的名字.
 36         ordering:排序,使用一个列表,可以设定多个参数,按给定字段顺序排序,倒序在排序字段前加负号\'-\'.
 37 
 38     外键和表的关系 见博客 https://www.cnblogs.com/djtang/articles/13388301.html
 39 外键所放位置
 40     一对一:外键放在不常用的一方
 41     一对多:外键放在多的一方
 42     多对多:外键放在常用的一方
 43     外键字段为正向查询字段,related_name=\'学生班级\'是反向查询字段别名
 44 外键如何断关联
 45     设置外键字段db_constraint=False
 46 外键间的级联关系
 47     一对一:学生没有了,学生证也没有了=============> on_delete=models.CASCADE,
 48     一对多:班级没有了,学生还是哪个班级的学生=======> on_delete=models.DO_NOTHING
 49     一对多:班级没有了,学生没有班级,班级为空========> on_delete=models.SET_NULL, null=True, blank=True
 50     一对多:班级没有了,学生进入默认的班级(默认值)====> on_delete=models.SET_DEFAULT, default="默认值"
 51     多对多:不能设置 on_delete,实际关系中,ORM默认关系表中两个外键都是级联
 52 choices设计注意字段的属性,两都要一致,SmallIntegerField,后面写入数据的字段属性就是数据字型的1.2,CharField后面就要写成字符串\'1\',\'2\'
 53     性别 = models.SmallIntegerField(max_length=2, blank=True, choices=((1, \'男\'), (2, \'女\')))
 54     性别 = models.CharField(max_length=2, blank=True, choices=((\'1\', \'男\'), (\'2\', \'女\')))
 55 多选框的使用
 56     1.pip install django-multiselectfield
 57     2.from multiselectfield import MultiSelectField
 58     3.爱好 = MultiSelectField(u"爱好1", choices=((\'打球1\', u\'篮球\'), (\'足球1\', u\'足球\'), (\'french\', \'法语\')))
 59     4."爱好1"是在admin显志的列标题,\'打球1\'是在admin显示页面的显示的内容,"u\'篮球\'"是在增加和编辑的显示的内容,一定要加u,不然编辑会报错!
 60 django modeladmin重新排序
 61     方法1:admin左则菜单app下数据库表是按verbose_name排序的
 62     方法2:
 63     1.pip install django-modeladmin-reorder
 64     2.INSTALLED_APPS中配 \'admin_reorder\',
 65     3.将modeladminireorder添加到中间件类,MIDDLEWARE_CLASSES 中 \'admin_reorder.middleware.ModelAdminReorder\',
 66     4.
 67 
 68     """
 69     # AbstractUser中已有字段:
 70     # id(主键字段)
 71     # password(密码)
 72     # last_login(最后登录时间)
 73     # is_superuser(是否超级用户)
 74     # username(用户名,不要改动)
 75     # first_name(第一次用户名)
 76     # last_name(最后一次用户名)
 77     # email(邮箱)
 78     # is_staff(是否职员)
 79     # is_active(是否激活)
 80     # date_joined(加入时间)
 81     二维码 = models.CharField(max_length=64, blank=True, null=True, )  # 不重复v
 82     个人编号 = models.CharField(max_length=16, unique=True)  # 必填,唯一.
 83     真实姓名 = models.CharField(max_length=16)  # 必填,可重复
 84     性别 = models.SmallIntegerField(blank=True, null=True, choices=((1, \'\'), (2, \'\')))  # 可填
 85     手机号码 = models.CharField(max_length=11, unique=True, blank=True, null=True)  # 必填,唯一,在第一次增加管理员时要用blank=True
 86     # 一个(用户个人)对应一个(公司),一个(公司)有多个(用户个人),删除(用户个人)时(公司企业信息表)中(用户个人)为空,(公司企业信息表)中的(公司)还在
 87     # related_name=\'人员_公司\'就是通过此表UserProfile查公司企业信息表Company,直接就是:全部公司信息 = Company.人员_公司.all()
 88     公司名称 = models.ForeignKey(\'Company\', on_delete=models.SET_NULL, null=True, blank=True, related_name=\'人员公司\')
 89     部门名称 = models.ForeignKey(\'Department\', on_delete=models.SET_NULL, null=True, blank=True, related_name=\'人员部门\')
 90 
 91     class Meta:
 92         verbose_name = \'01-用户个人信息\'
 93         verbose_name_plural = verbose_name
 94 
 95     def __str__(self):  # 必需有值的字段,当前对象的描写
 96         return self.username  # 返回此对象的用户名username
 97 
 98 
 99 # 02-公司部门信息
100 class Department(BaseModel):
101     部门编码 = models.CharField(max_length=16, unique=True)  # 必填,唯一.
102     部门名称 = models.CharField(max_length=24, unique=True)  # 必填,唯一.
103     # 基于平台设计的一对多关系,对应公司进入对应的部门,不能A公司进入B公司的部门
104     # 一个(公司部门)对应一个(公司),一个(公司)有多个(公司部门),删除(公司部门)时(公司企业信息表)中(公司部门)为空,(公司企业信息表)中的(公司)还在
105     公司名称 = models.ForeignKey(\'Company\', on_delete=models.SET_NULL, null=True, blank=True, related_name=\'部门公司\')
106 
107     class Meta:
108         verbose_name = \'02-公司部门信息\'
109         verbose_name_plural = verbose_name
110 
111     def __str__(self):
112         return self.部门名称
113 
114 
115 # 03-客商公司信息(自已/供应商/客户)
116 class Company(BaseModel):
117     公司编号 = models.CharField(max_length=16, unique=True)  # 必填,唯一.
118     公司全称 = models.CharField(max_length=64, unique=True)  # 必填,唯一.
119     公司简称 = models.CharField(max_length=32, unique=True)  # 必填,唯一.
120     # 使用ImageField类型,需要按装图像处理标准库Pillow,default=\'\'相当于blank=True, null=True
121     公司logo = models.ImageField(max_length=128, upload_to=\'A001jcxx/company/image/%y/%m\', null=True, blank=True)  # 可填
122     公司地址 = models.CharField(max_length=128, blank=True, null=True)  # 可填
123 
124     class Meta:
125         verbose_name = \'03-01-客商公司信息\'
126         verbose_name_plural = verbose_name
127 
128     def __str__(self):
129         return self.公司全称

 

步骤2:必需在settings中设定,配置django认证系统使用的模型类AbstractUse,必需配置 AUTH_USER_MODEL= "APP名.UserProfile",这里的APP名是你自已取的,后面UserProfile就是上面的表名

步骤3:在对应 app 的  admin.py  中注册上在三个表

 1 # 002-用户信息表
 2 @admin.register(UserProfile)
 3 class UserProfileAdmin(UserAdmin):  # 相当于注册到UserAdmin中了.重载他的验证方法和显示字段配置,配置要按UserAdmin的方法配置.
 4     pass
 5 
 6 
 7 # 003-部门信息表
 8 @admin.register(Department)
 9 class DepartmentAdmin(admin.ModelAdmin):
10     pass
11 
12 
13 # 004 - 企业信息表(自已/供应商/客户)
14 @admin.register(Company)
15 class CompanyAdmin(admin.ModelAdmin):
16     pass

步骤4:生成表结构

  python manage.py makemigrations

  python manage.py migrate

  注意:对数据库中已有数据作表结构变动时,可能会提示一些必填字段信息的提示,不能直接重新同步数据库,此时的解决方法有两种,一种是,设置新增字段的default=\'xxx\'某个值, 但是这种通用性不是很好。 另外一种是,设置该字段null=True,即允许为空即可,我一般都删库重来.

步骤5:运行项目,登陆管理界面

python manage.py runserver
 
访问URL:http://IP:8000/admin

四  显示设置(在对应 app 的  admin.py  中配置)

1.用户表 UserProfileAdmin 中增加页面和修改页面相关字段的配置,主要是新增字段,同时密码是密文的,解决是明文的问题.可根据自已的需求自行再调整

 1 # 002-用户信息表
 2 @admin.register(UserProfile)
 3 class UserProfileAdmin(UserAdmin):
 4     # 1.增加用户信息页面字段设置,对字段分组分块设计的.
 5     add_fieldsets = (
 6         # 用户信息块,None是这个块块头,表示没有块头
 7         (None, {u\'fields\': (\'username\', \'password1\', \'password2\')}),
 8         # 增加用户信息页面字段设置,字段显示按排列顺序显示的,这里的块头就是\'用户详情\'
 9         ((\'用户详情\'), {\'fields\': (\'人员编号\', \'性别\', \'手机号码\', \'企业名称\', \'部门名称\', \'is_staff\', \'is_superuser\')}),)
10     # 2.修改页面字段设置,对字段分组分块设计的.
11     fieldsets = (
12         # 个人信息块
13         ((\'用户信息\'), {\'fields\': (\'人员编号\', \'性别\', \'username\', \'password\', \'email\', \'手机号码\', \'企业名称\', \'部门名称\')}),
14         # 权限信息块
15         ((\'用户权限\'), {
16             \'fields\': (\'is_active\', \'is_staff\', \'is_superuser\', \'groups\', \'user_permissions\')}),
17     )

 修改后的增加用户信息页面,这时注册后用户密码就是密文的了,在修改用户信息页面就看不到密码了,要用增加的用户登录admin必需在注册时把 职员状态 勾上,不然登录不了后台.

  

2.显示用户页面字段的设置  

 1 # 002-用户信息表
 2 @admin.register(UserProfile)
 3 class UserProfileAdmin(UserAdmin):
 4     # 1.增加用户信息页面字段设置,对字段分组分块设计的.
 5     add_fieldsets = (
 6         # 用户信息块,None是这个块块头,表示没有块头
 7         (None, {u\'fields\': (\'username\', \'password1\', \'password2\')}),
 8         # 增加用户信息页面字段设置,字段显示按排列顺序显示的,这里的块头就是\'用户详情\'
 9         ((\'用户详情\'), {\'fields\': (\'人员编号\', \'性别\', \'手机号码\', \'企业名称\', \'部门名称\', \'is_staff\', \'is_superuser\')}),)
10     # 2.修改页面字段设置,对字段分组分块设计的.
11     fieldsets = (
12         # 个人信息块
13         ((\'用户信息\'), {\'fields\': (\'人员编号\', \'性别\', \'username\', \'password\', \'email\', \'手机号码\', \'企业名称\', \'部门名称\')}),
14         # 权限信息块
15         ((\'用户权限\'), {
16             \'fields\': (\'is_active\', \'is_staff\', \'is_superuser\', \'groups\', \'user_permissions\')}),
17     )
18     # 3.显示用户页面字段的设置
19     list_display = (  # 展示页面显示字段设置,字段顺序应是排列顺度,第一个字段名默认可以点去明细编辑.
20         \'is_staff\', \'人员编号\', \'性别\', \'username\', \'手机号码\', \'email\', \'部门名称\', \'企业名称\', \'is_superuser\', \'last_login\',
21         \'创建时间\',\'更新时间\', \'删除标记\')

显示页面配置后如下图:

 3.改变超级用户状态和删除标记下显示的方法,如上图

 1 # 002-用户信息表
 2 @admin.register(UserProfile)
 3 class UserProfileAdmin(UserAdmin):
 4     # 1.增加用户信息页面字段设置,对字段分组分块设计的.
 5     add_fieldsets = (
 6         # 用户信息块,None是这个块块头,表示没有块头
 7         (None, {u\'fields\': (\'username\', \'password1\', \'password2\')}),
 8         # 增加用户信息页面字段设置,字段显示按排列顺序显示的,这里的块头就是\'用户详情\'
 9         ((\'用户详情\'), {\'fields\': (\'人员编号\', \'性别\', \'手机号码\', \'企业名称\', \'部门名称\', \'is_staff\', \'is_superuser\')}),)
10     # 2.修改页面字段设置,对字段分组分块设计的.
11     fieldsets = (
12         # 个人信息块
13         ((\'用户信息\'), {\'fields\': (\'人员编号\', \'性别\', \'username\', \'password\', \'email\', \'手机号码\', \'企业名称\', \'部门名称\')}),
14         # 权限信息块
15         ((\'用户权限\'), {
16             \'fields\': (\'is_active\', \'is_staff\', \'is_superuser\', \'groups\', \'user_permissions\')}),
17     )
18 
19     # 4.改变删除标记下显示的方法,在list_display中不要加引号,list_display必需放到函数方法后面
20     def 删除标记(self):  # 这个方法名"删除标记"在 list_display 里配置时不要加引号
21         if self.删除标记:
22             return \'\'
23         else:
24             return \'\'
25 
26     def 登录权限(self):  # 这个方法名"登录权限"在 list_display 里配置时不要加引号
27         if self.is_staff:
28             return \'\'
29         else:
30             return \'\'
31 
32     def is_superuser(self):  # 这个方法名"is_superuser"在 list_display 里配置时不要加引号
33         if self.is_superuser:
34             return \'\'
35         else:
36             return \'\'
37     is_superuser.short_description = \'是否超级用户\'  # 将 is_superuser 在展示页面显示为中方 \'是否超级用户\',
38     # 3.展示页面显示字段设置,字段顺序应是排列顺度,第一个字段名默认可以点去明细编辑.
39     list_display = (
40         \'人员编号\', \'性别\', \'username\', \'手机号码\', \'email\', \'部门名称\', \'企业名称\',  \'last_login\', \'创建时间\',
41         \'更新时间\', 登录权限, is_superuser, 删除标记)

配置后显示如下:

 

 

 

五  其它配置网上讲的太多就抄一下吧备查

# 在列表页显示的字段,默认会显示所有字段,有对应的方法可以重写
list_display = (\'__str__\',)
# 在列表页显示的字段中,可以链接到change_form页面的字段
list_display_links = ()
# 右侧的筛选,必须是字段,可以继承自SimpleListFilter来自定义筛选字段和规则,SimpleListFilter的方法在后面详细介绍
list_filter = ()
# 联表查询是否自动查询,可以是布尔,列表或元组,如果是列表或元组,则级联查询指定的字段
list_select_related = False
# 列表页每页展示的条数
list_per_page = 100
# 分页,显示全部,真是数据小于该值时才会显示全部
list_max_show_all = 200
# 在列表页可以编辑的字段
list_editable = ()
# 在列表页可以模糊搜索的字段
search_fields = ()
# 对Date和DateTime类型进行搜索
date_hierarchy = None
# 在change_form页面,按钮为,save按钮的值(save as new和save add another)
save_as = False
# 点击保存并继续编辑
save_as_continue = True
# save按钮的位置,是True则显示在页面上方
save_on_top = False
# 自定义分页类
paginator = Paginator
# 详细页面,删除、修改,更新后跳转回列表后,是否保留原搜索条件管理员现在在创建,编辑或删除对象后保留列表视图中的过滤器。
# 可以将此属性设置为False,以恢复之前清除过滤器的行为。
preserve_filters = True
# 在详情页面,如果有FK到其他表,在详情页中可以动态的填加或删除级联数据
inlines = []
admin中action操作的设置
admin中的action是指在列表页的动作,默认为删除所选的条目,可以自定义填加动作,将动作注册到action中,需要是一个方法
# 定制action中的操作
actions = []
action_form = helpers.ActionForm
# action选项显示的位置,页面上方或者页面下方
actions_on_top = True
actions_on_bottom = False
# 是否显示action选择的个数
actions_selection_counter = True
checks_class = ModelAdminChecks
BaseModelAdmin中的属性
除了ModelAdmin中的属性,也可以自定义在其父类BaseModelAdmin中的属性和方法,是一些通用的,在继承子BaseModelAdmin的类中也可以完成的属性设置.一般是详情页的属性.
# 自动补全,外键查询数据多时,方便查找
autocomplete_fields = ()
# 详情页,针对外键和M2M字段变成input框形式
raw_id_fields = ()
# 详情页面展示的字段
fields = None
# 详情页面排除的字段,字段可以是数据库中的也可以是自定义的
exclude = None
# 在详情页面对数据进行分隔显示,对应到admin模板中的\'fieldsets.html\'
fieldsets = None
# 为详情页指定form表单,可以自定义显示的数据,字段
form = forms.ModelForm
# 下面两个是M2M显示时,数据移动选择.可以参考admin中用户的权限操作
filter_vertical = () # 纵向展示
filter_horizontal = () # 横向展示
# 详情页面使用radio显示选项,FK默认使用select
radio_fields = {}
# 填加页面,在某字段输入值后,自动填加到指定字段
# prepopulated_fields = {"email": ("user",)},email字段会在用户填加user字段时自动填充
prepopulated_fields = {}
# 详情页指定显示的插件,后面详细说明
formfield_overrides = {}
# 详情页面的只读字段
readonly_fields = ()
# 详情页面排序规则
ordering = None
# 禁止某些排序,为空则禁止所有的排序
sortable_by = None
# 编辑时是否在页面上显示view on set,可以通过方法来返回一个链接,后面说明
view_on_site = True
# 列表页,模糊搜索后面显示的数据个数样式
# 为True是显示条数,为False时显示全部
show_full_result_count = True
checks_class = BaseModelAdminChecks

 

六  功能的二次开发

1.自定义字段

方法1:在 models.py 中定议

 

方法2:在 admin.py 中定议

 自定义字段名: times.short description = \'字段别名\'

 

2.自定义 html 语言

2.1 导入方法

 

2.2 使用方法

 

3.imageField 显示方法

3.1 导入方法

 

 3.2 使用方法

 

3.获取数据函数

 

 4.获职保存函数