一 使用环境
开发系统: 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.获职保存函数