美文网首页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