• 项目一:CRM(客户关系管理系统)--11


    接着搞起烂摊子。

    前面我们简单的实现了全篇只读限制,但是存在安全隐患。在解决此隐患之前,我们需要先之道如何实现自定义后台表单的验证。

    1. 原生admin中自定义表单验证

    说起表单验证,在前面提过FormMoldeForm的相关使用,这里我们要通过另一个方法进行处理。

    我们通过使用clean()方法实现对全部字段进行验证操作,clean_name()单独对每个字段进行验证处理,其中name对应字段名称(必须保持一致)。

    这些实际的使用方式就不具体介绍了,简单的介绍一下实现原理:

    实际的代码中,我们只需要在定义的From文件中添加即可:

     1 from django import forms
     2 
     3 class LoginForm(forms.Form):
     4  
     5 def clean_user(self):
     6 c = UserProfile.objects.filter(name=self.cleaned_data[‘user’]).count()
     7 if not c:
     8 return self.cleaned_data[‘user’]
     9 else:
    10 raise ValueError(“用户名已经存在”, code=”asdasd”)
    11  
    12 def clean_pwd(self):
    13 pass
    14  
    15 def clean(self): # 对整体验证
    16 c = UserProfile.objects.filter(name=self.cleaned_data[“user”], pwd=self.cleaned_data[“pwd”])
    17 if c:
    18 return self.cleaned_data
    19 else:
    20 raise ValueError(“用户名密码错误”)

    这里只是提供简单的示例。

    2. 构造自定义功能

    2.1 所有字段添加自定义clean()验证

    前面我们动态创建了MoelForm的每个具体类,我们要为每个类中添加clean()验证。既然,我们动态创建了类,那么对应的类的方法也是很简单的。

    在上面的图中,我们可以看出clean()方法调用的原理,下面结合之前的只读限制来使用它,上一篇文章中我们实现了只读功能,但是并没有安全的验证机制,为了安全做如下操作:

    这里先不做多对多的关系处理

    2.2 不处理多对多关系

    king_admin应用目录下的forms.py中添加如下代码:

     1 def __new__(cls, *args, **kwargs):
     2 # 遍历数据库的所有字段和字段对应的对象
     3 for field_name, field_obj in cls.base_fields.items():
     4 # 为字段对象的组件添加class属性
     5 field_obj.widget.attrs[‘class’] = ‘form-control’
     6  
     7 #添加只读限制
     8 if not hasattr(admin_class, ‘is_add_form’): #排除添加页面
     9 if field_name in admin_class.readonly_fields:
    10 field_obj.widget.attrs[‘disabled’] = ‘disabled’
    11 # 创建当前类的实例—>即创建子类
    12 return ModelForm.__new__(cls)
    13  
    14 #为每个ModelForm具体的类创建clean()方法
    15 def clean_init(self):
    16 “””
    17 :param self: 表单对象
    18 :return:
    19 “””
    20 error_list = [] #存储错误
    21 for field in admin_class.readonly_fields:
    22 #获取数据库的数据
    23 field_db = getattr(self.instance, field)
    24 #获取前端数据
    25 field_input = self.cleaned_data.get(field)
    26 #判断
    27 if field_db != field_input:
    28 #触发错误,固定格式
    29 error_list.append(
    30 ValidationError(
    31 ‘Field %(field)s is readonly,data should be %(value)s’,
    32 code=’invalid’,
    33 params={‘field’: field,’value’: field_db}
    34 )
    35 )
    36 #集中错误
    37 if error_list:
    38 raise ValidationError(error_list)
    39  
    40 <——————-为对象添加属性——————————–
    41 #为该类添加__new__静态方法,当调用该类时,会先执行__new__方法,创建对象
    42 # 这里会覆盖父类的__new__
    43 setattr(_model_form_class, ‘__new__’, __new__)
    44  
    45 #添加clean()方法到生成的表单类
    46 setattr(_model_form_class, ‘clean’, clean_init)
    47  
    48 return _model_form_class
    49  

    基本的逻辑实现完毕,修改指定的只读字段

     1 ...
     2 #自定义类,显示特定字段
     3 class CustomerAdmin(ModelAdmin):
     4     list_display = ['id', 'qq','name','source','consultant','consult_course','date','status']
     5     list_filters = ['source','consultant','consult_course','status']
     6     search_fields = ['qq', 'name', 'consultant__name', ]
     7     ordering = 'date'
     8     # filter_horizontal = ['tags']
     9     readonly_fields = ['qq', 'name'] #添加该字段
    10     readonly_table = False
    11     list_per_page = 2
    12 ...

    效果如下:

    2.3 处理多对多关系

  • 相关阅读:
    using vb.net export a datatable to Excel and save as file
    selection sort with objective c
    stdin和STDIN_FILENO的区别
    stdin和STDIN_FILENO的区别
    linux系统kbhit的几种实现
    成为掌握企业聘用趋势的人才
    linux系统kbhit的几种实现
    c_lflag中ICANON的作用
    常量字符串的问题
    mmsbitfields gcc和vc关于位域那点事
  • 原文地址:https://www.cnblogs.com/eaglesour/p/8098750.html
Copyright © 2020-2023  润新知