Django自定义Admin后台报错提示和数据校验

     阅读:50

Django的admin后台是个好东西,接业务需求,需要开发一个单独的修改用户名的页面,没有前端支持只能考虑使用admin了。

数据模型

from django.db import models

   class Order(models.Model):
    """ 订单表 """
    serial = CharField(max_length=64, verbose_name="编号", help_text="编号")

class User(models.Model):
	""" 用户表 """
	order = ForeignKey(Order, on_delete=SET_NULL, verbose_name="关联订单", help_text="关联订单", default=None, null=True)
    id_no = CharField(max_length=24, verbose_name="身份证号码", help_text="身份证号码")
    name = CharField(max_length=64, verbose_name="姓名", help_text="姓名")
    mobile = CharField(max_length=11, verbose_name="手机号", help_text="手机号", default=None, null=True, blank=True)
    phone = CharField(max_length=11, verbose_name="还是手机号", help_text="还是手机号", default=None, null=True, blank=True)
    remark = CharField(max_length=256, verbose_name="备注", help_text="备注", default=None, null=True, blank=True)

    class Meta:
        verbose_name_plural = '修改用户名操作'
  • verbose_name_plural,在admin后台展示的表名。

admin配置

基础配置

from django.contrib import admin

@admin.register(User)
class UserAdmin(admin.ModelAdmin):
	form = EditLaborForm
    list_display = ['name', 'id_no']
    search_fields = ['name', 'order__serial']
    fields = ("name", 'id_no', 'mobile', 'phone', 'remark', 'order')
    readonly_fields = ("remark")
    prepopulated_fields = {'phone': ('mobile',)}
    raw_id_fields = ("order")
    list_per_page = 10
  • @admin.register(User),注册User表。
  • list_display,控制数据列表页显示的字段。
  • search_fields,查询字段,也可以直接查询外键关联表的字段。
  • fields,数据详情页显示的字段。
  • readonly_fields,只读的字段,不能操作修改。
  • prepopulated_fields,自动填充字段,例:phone会同步显示在mobile输入框中输入的内容,:该方法不能同步中文,只能同步数字或者字母。
  • raw_id_fields,外键关联的字段输入框会从原来默认的下拉选择框变为输入框,可以点击右面的放大镜图标,查询选择已有数据。
  • list_per_page,每页展示的数据量。

进阶配置

加数据校验

from django import forms

class UserForm(forms.ModelForm):
	remark = CharField(max_length=64, required=True, label='必填的备注')

	class Meta:
        model = User
        exclude = ['id']

@admin.register(User)
class UserAdmin(admin.ModelAdmin):
	form = UserForm
	list_display = ['name', 'id_no']
    search_fields = ['name', 'order__serial']
    fields = ("name", 'id_no', 'mobile', 'phone', 'remark', 'order')
    readonly_fields = ("remark")
    prepopulated_fields = {'phone': ('mobile',)}
    raw_id_fields = ("order")
    list_per_page = 10
  • 原有的remark字段是直接根据model中的配置进行校验的,是非必填的,但是现在重新定义了form,就会使用自定义的UserForm进行校验数据。UserForm中定义了remarkrequired参数为True,所以现在remark变为了必填字段,用户不填写该字段会在点击保存时在必填的备注一栏上显示,该字段为必填项。

自定义报错内容和校验

  • 重构UserFormclean方法。
    class UserForm(forms.ModelForm):
    	remark = CharField(max_length=64, required=True, label='必填的备注')
    
    	class Meta:
            model = User
            exclude = ['id']
    
        def clean(self):
            """ 校验后的数据处理, 和手动处理方法 """
            cleaned_data = self.cleaned_data
            phone = cleaned_data.get('phone')
            mobile = cleaned_data.get('mobile')
            errors = {}
            if phone != mobile:
                errors.update({"phone": '填写的手机号重复', "mobile": '填写的手机号重复'})
            self.add_error(field=None, error=errors)
    
  • self.cleaned_data,进行校验后的数据。
  • self.add_error(),添加报错内容,参数field为报错字段,参数error为报错内容。当error字段是一个字典时field字段需要填None,然后会自动取值error参数中的key作为报错字段, value作为报错内容。报错内容会显示在对应字段的输入框上面。

重构创建的方法

  • 重构UserAdminsave_model方法。
    def save_model(self, request, obj, form, change):
       """ 创建用户 """
        if request.POST:
           return super(EditLaborAdmin, self).save_model(request, obj, form, change)
    

处理详情的数据

  • 重构UserAdminrender_change_form方法。
    def render_change_form(self, request, context, add=False, change=False, form_url='', obj=None):
        """ 重构详情里的返回数据 """
        # oss地址加上token
        if obj and obj.mobile:
            obj.mobile = f'+86{obj.mobile}'
        return super(EditLaborAdmin, self).render_change_form(request, context, add, change, form_url, obj)