Django内置了强大的Admin后台系统,并且是默认启用的。在根目录的urls.py中可以看到Admin的URL地址信息,在浏览器上输入http://127.0.0.1:8000/admin就能访问Admin后台系统。
中文语言设置
初次访问Admin后台系统时,可能显示的会是英文,这时候只需要到根目录的settings.py中设置一下即可,有两种方法:
- 设置中间件
MIDDLEWARE = [
'django.middleware.security.SecurityMiddleware',
'django.contrib.sessions.middleware.SessionMiddleware',
#使用中文
'django.middleware.locale.LocaleMiddleware',
'django.middleware.common.CommonMiddleware',
'django.middleware.csrf.CsrfViewMiddleware',
'django.contrib.auth.middleware.AuthenticationMiddleware',
'django.contrib.messages.middleware.MessageMiddleware',
'django.middleware.clickjacking.XFrameOptionsMiddleware',
]
- 设置LANGUAGE_CODE
LANGUAGE_CODE = 'zh-Hans'
创建超级用户
访问后台系统还需要输入用户名和密码。因此,我们还需要创建一个超级用户。在创建用户之前,确保项目的模型在数据库中有相应的数据表。创建方法仍然由Django的manage.py完成,在项目目录下输入以下命令:
E:\mysite>python manage.py createsuperuser
Username (leave blank to use 'user'): root
Email address: 12345678@qq.com
Password:
Password (again):
The password is too similar to the email address.
This password is too short. It must contain at least 8 characters.
This password is too common.
This password is entirely numeric.
Bypass password validation and create user anyway? [y/N]: y
Superuser created successfully.
依次输入用户名root,email、password,如果密码过于简单,还会提示是否仍然创建,输入y,创建超级用户成功!
使用刚才创建的账户和密码即可进入Admin后台管理系统的页面。
image.png
注册模型
在Admin后台系统中,可以看到站点管理下只有用户和组的管理,这是Django内置的认证系统。要将index中自定义的模型Product和Type展示在后台系统中,则需要在index的admin.py中添加如下代码:
from django.contrib import admin
from .models import *
# Register your models here.
#方法一:将模型直接注册到admin后台。
# admin.site.register(Product)
#方法二:自定义ProductAdmin类并继承ModelAdmin
#注册方法1,使用Python装饰器将ProductAdmin和模型Product绑定并注册到后台
@admin.register(Product)
class ProductAdmin(admin.ModelAdmin):
#设置显示的自断
list_display = ['id', 'name', 'weight', 'size', 'type']
#注册方法2
admin.site.register(Product, ProductAdmin)
日常开发中,一般采用方法二来实现注册。
image.png
刷新Admin后台系统页面,可以看到站点管理出现了INDEX,代表项目index,INDEX下的Products是index中的模型Product,对应数据表index_product。
Admin的基本设置
虽然我们成功将数据表index_product成功展现在站点管理的页面,但对一个不会网站开发的使用者来说,可能无法理解INDEX和Products的函数,因此,还需要将INDEX和Product转换成具体的中文内容。将INDEX和Products设置中文显示需要分别使用不同的方法实现,因为INDEX和Products在项目中分别代表不同的意思,前者是一个App的命名,后者是一个App中定义的模型。
设置App名中文显示
首先实现INDEX的中文显示,主要由App的__init__.py
文件实现:
#index 的 __init__.py文件
from django.apps import AppConfig
import os
#修改App在Admin后台显示的名称
#default_app_config的值来自apps.py的类名
default_app_config = 'index.IndexConfig'
#获取当前App的命名
def get_current_app_name(_file):
return os.path.split(os.path.dirname(_file))[-1]
#重写类IndexConfig
class IndexConfig(AppConfig):
name = get_current_app_name(__file__)
verbose_name = '网站首页'
当项目启动时,程序会从初始化文件__init__
获取重写的IndexConfig类,类属性verbose_name用于设置INDEX的中文内容。
设置模型中文显示
接下来将Products设置中文显示,在models.py中设置类Meta的类属性verbose_name_plural即可实现。
#models.py
class Product(models.Model):
id = models.AutoField(primary_key=True)
name = models.CharField(max_length=50)
weight = models.CharField(max_length=20)
size = models.CharField(max_length=20)
type = models.ForeignKey(Type, on_delete=models.CASCADE)
#设置返回值
def __str__(self):
return self.name
class Meta:
#如只设置verbose_name,在Admin会显示为“产品信息s”
verbose_name = '产品信息'
verbose_name_plural = '产品信息'
设置Admin网页标题信息
除此之外,还可以进一步完善Admin网页标题信息,在App的admin.py中添加以下代码
#修改title和header
admin.site.site_title = '手机后台管理'
admin.site.site_header = '我的手机后台'
image.png
表头信息的中文设置
然后我们点击产品信息,进入模型Product的数据页面,会发现表头信息显示的是模型的字段,要让数据表头以中文的形式展现,我们需要在定义模型的字段时,添加参数verbose_name。该参数作为第一个参数时,可以省略参数名,在其他位置时必须加上参数名verbose_name。
#index 的 models.py
class Product(models.Model):
id = models.AutoField(verbose_name='序号',primary_key=True)
name = models.CharField('名称',max_length=50)
weight = models.CharField('重量',max_length=20)
size = models.CharField('尺寸',max_length=20)
type = models.ForeignKey(Type, on_delete=models.CASCADE,verbose_name='产品类型')
image.png
产品类型的中文显示
上图可以发现,产品类型的数据是一个模型Type对象。因此,在模型Type中定义__str__
函数,设置模型的返回值。
#index 的 models.py
class Type(models.Model):
id = models.AutoField('序号', primary_key=True)
type_name = models.CharField('产品类型', max_length=20)
#设置返回值
def __str__(self):
return self.type_name
image.png
设置搜索框、过滤器、排序方式、时间选择器等
当一个数据表中存储了成千上万的数据时,查找功能就时必要的。Django在admin.py的ProductAdmin类中设置属性search_fields
就可以实现搜索查找。
#admin.py 中的 ProductAdmin类
@admin.register(Product)
class ProductAdmin(admin.ModelAdmin):
#设置模型字段,用于Admin后台数据的表头设置
list_display = ['id', 'name', 'weight', 'size', 'type']
#设置可搜索的字段并在Admin后台数据生成搜索框,如有外键,应使用双下划线连接两个模型的字段
search_fields = ['id', 'name', 'type__type_name']
#设置过滤器,在后台数据的右侧生成导航栏,如有外键,应使用双下划线连接两个模型的字段
list_filter = ['name', 'type__type_name']
#设置排序方式,['id']为升序,['-id']为降序
ordering = ['id']
#设置时间选择器,如字段中有时间格式才可以使用
date_hierarchy = Field
#在添加新数据时,设置可添加数据的字段
fields = ['name', 'weight', 'size', 'type']
#设置只读字段,在修改或新增数据时,使其无法设置
readonly_fields = ['name']
Admin的二次开发
上述都是Admin的基本设置,但每个网站的功能和需求都是各不相同的,所以Admin后台功能也有所差异。因此,通过重写ModelAdmin的方法可以实现Admin的二次开发,满足多方面的开发需求。
函数 get_readonly_fields
函数get_readonly_fields 和属性readonly_fields的功能相似,不过比后者更强大。使用get_readonly_fields可以实现不同的用户角色来决定字段的可读属性,如:
#admin.py 中的 ProductAdmin类
class ProductAdmin(admin.ModelAdmin):
# ...
#以上的代码省略
#重写get_readonly_fields函数,设置超级用户和普通用户的权限
def get_readonly_fields(self, request, obj=None):
if request.user.is_superuser:
self.readonly_fields = []
else:
self.readonly_fields = ['name']
return self.readonly_fields
设置字段格式
在后台预览模型Product的数据信息时,数据表的表头是由属性 list_display所定义的。如果要对某些字段的数据进行特殊处理,如设置数据的字体颜色,以模型Product的type字段为例:
#index 的 models.py 的ProductAdmin类
class ProductAdmin(admin.ModelAdmin):
# ...
#以上的代码省略
#自定义函数,设置字体颜色
def colored_type(self):
if '手机' in self.type.type_name:
color_code = 'red'
elif '平板电脑' in self.type.type_name:
color_code = 'blue'
elif '智能穿戴' in self.type.type_name:
color_code = 'green'
else:
color_code = 'yellow'
return format_html('<span style="color: {};">{}</span>',color_code,self.type)
#设置Admin的标题
colored_type.short_description = '带颜色的产品类型'
然后再到admin.py的ProductAdmin类中添加自定义字段
#admin.py 的 ProductAdmin类中
#添加自定义字段,colored_type来自于模型Product
list_display.append('colored_type')
运行结果如下:
image.png
函数 get_queryset
函数 get_queryset根据不同用户角色设置数据的访问权限,该函数可以将一些重要的数据进行过滤。以模型Product为例,在admin.py的类ProductAdmin中重写函数get_queryset。
#admin.py 的 ProductAdmin类
class ProductAdmin(admin.ModelAdmin):
# ...
#以上的代码省略
#重写get_queryset函数,根据当前用户名设置数据访问权限,非超级用户仅能读取前5条数据
def get_queryset(self, request):
qs = super(ProductAdmin, self).get_queryset(request)
if request.user.is_superuser:
return qs
else:
return qs.filter(id__lt=6)
image.png
函数formfield_for_foreignkey
该函数用于在新增或修改数据的时候,设置外键的可选值。如果在模型中将某字段定义为外键类型,当新增数据时,该字段为一个下拉框控件,下拉框中的数据来自于该字段所指向的模型。
如果想对下拉框中的数据实现过滤功能,可以对函数formfield_for_foreignkey进行重写。
#admin.py 的 ProductAdmin类
class ProductAdmin(admin.ModelAdmin):
# ...
#以上的代码省略
#重写formfield_for_foreignkey函数,新增或修改数据时,设置外键可选值
def formfield_for_foreignkey(self, db_field, request, **kwargs):
#一个模型可以定义多个外键,所以首先要判断外键名
if db_field.name == 'type':
if not request.user.is_superuser:
kwargs["queryset"] = Type.objects.filter(id__lt=4)#非超级用户返回前3个类型
return super(admin.ModelAdmin, self).formfield_for_foreignkey(db_field, request, **kwargs)
image.png
函数 save_model
函数save_model是在新增或修改数据时,点击保存按钮所触发的功能,该函数主要对输入的数据进行入库和更新处理。如果想在这功能中加入一些特殊的功能需求,可以对该函数进行重写。比如对数据的修改实现一个日志记录,那么函数save_model的实现代码如下:
#admin.py 的 ProductAdmin类
class ProductAdmin(admin.ModelAdmin):
# ...
#以上的代码省略
#修改保存方法
def save_model(self, request, obj, form, change):
if change:
#获取当前用户名
user = request.user
#使用模型获取数据, pk代表具有主键属性的字段
name = self.model.objects.get(pk=obj.pk).name
#使用表单获取数据
weight = form.cleaned_data['weight']
#写入日志文件
f = open('e://mysite/mysite_log.txt','a')
f.write('产品:' + str(name) + ',被用户:' + str(user) + ' 修改' + '\r\n')
f.close()
else:
pass
#使用super可使自定义save_model既保留父类已有功能又添加自定义功能
super(ProductAdmin, self).save_model(request, obj, form, change)
此外,还有数据删除所执行的函数delete_model,代码如下:
#admin.py 的 ProductAdmin类
class ProductAdmin(admin.ModelAdmin):
# ...
#以上的代码省略
def delete_model(self, request, obj):
pass
super(ProductAdmin, self).delete_model(request, obj)
网友评论