美文网首页Python学习资料整理Python
(9) Django - Admin后台系统

(9) Django - Admin后台系统

作者: libdream | 来源:发表于2019-03-11 15:02 被阅读22次

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)

相关文章

网友评论

    本文标题:(9) Django - Admin后台系统

    本文链接:https://www.haomeiwen.com/subject/htbvpqtx.html