Django项目:CRM(客户关系管理系统)--38--30PerfectCRM实现King_admin编辑自定义字段验证
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 # kingadmin.py 2 # ————————04PerfectCRM实现King_admin注册功能———————— 3 from crm import models 4 #print("kingadmin crm",models.Customer) 5 6 # ————————05PerfectCRM实现King_admin注册功能获取内存———————— 7 # from king_admin.base_admin import register,BaseAdmin 8 from king_admin.base_admin import site,BaseAdmin 9 # ————————05PerfectCRM实现King_admin注册功能获取内存———————— 10 11 # ————————24PerfectCRM实现King_admin自定义操作数据———————— 12 from django.shortcuts import render 13 # ————————24PerfectCRM实现King_admin自定义操作数据———————— 14 15 # ————————28PerfectCRM实现King_admin编辑限制———————— 16 from django.forms import ValidationError 17 from django.shortcuts import render,redirect 18 # ————————28PerfectCRM实现King_admin编辑限制———————— 19 20 #04客户信息表 21 class CustomerAdmin(BaseAdmin):#定制Djanago admin 22 list_display = ('id', 'qq', 'source', 'consultant', 'content', 'date') # 显示字段表头 23 24 # ————————11PerfectCRM实现King_admin分页显示条数———————— 25 list_per_page = 2 #分页条数 # 默认分页条数10 26 # ————————11PerfectCRM实现King_admin分页显示条数———————— 27 28 # ————————16PerfectCRM实现King_admin日期过滤———————— 29 # ————————15PerfectCRM实现King_admin多条件过滤———————— 30 # 过滤器(可以包含ManyToManyField) (注意加 逗号 , ) 31 # list_filter = ('source','consultant','consult_courses',) 32 list_filter = ('date','source','consultant','consult_courses',) 33 # ————————15PerfectCRM实现King_admin多条件过滤———————— 34 # ————————16PerfectCRM实现King_admin日期过滤———————— 35 36 # ————————18PerfectCRM实现King_admin搜索关键字———————— 37 #搜索(不能包含CharField)(注意加 逗号 , ) 38 search_fields = ('name','qq',) 39 # ————————18PerfectCRM实现King_admin搜索关键字———————— 40 41 # ————————26PerfectCRM实现King_admin自定义排序———————— 42 ordering = '-qq' #自定义排序,默认'-id' 43 # ————————26PerfectCRM实现King_admin自定义排序———————— 44 45 # ————————27PerfectCRM实现King_admin编辑复选框———————— 46 filter_horizontal = ('tags',) #复选框 47 # ————————27PerfectCRM实现King_admin编辑复选框———————— 48 49 50 51 # ————————24PerfectCRM实现King_admin自定义操作数据———————— 52 # from django.shortcuts import render 53 actions = ['test_actions',]#定制功能 #测试返回到一个新页面 54 def test_actions(self,request,arg2):#对应的函数 #request类自己的请求 #arg2类的内容 55 return render(request,"king_admin/table_index.html") 56 test_actions.short_description = "测试显示中文" 57 # ————————24PerfectCRM实现King_admin自定义操作数据———————— 58 59 # ————————28PerfectCRM实现King_admin编辑限制———————— 60 readonly_fields = ('qq', 'consultant',) # 不可修改 61 62 # ————————29PerfectCRM实现King_admin编辑自定义限制———————— 63 def default_form_validation(self,obj): 64 print('validation:制定的',obj.cleaned_data) 65 consult_course=obj.cleaned_data.get('content','')#自制验证字段 66 if len(consult_course)<10: 67 return ValidationError(#添加错误信息 返回 68 ("该字段%(field)s 咨询内容记录不能少于10个字符"), 69 code='invalid', 70 params={'field':'content',}, 71 ) 72 # ————————29PerfectCRM实现King_admin编辑自定义限制———————— 73 # ————————28PerfectCRM实现King_admin编辑限制———————— 74 75 # ————————30PerfectCRM实现King_admin编辑自定义字段验证———————— 76 def clean_name(self,obj,*args,**kwargs):#名称验证 单个 77 name=obj.cleaned_data['name'] 78 if not name: 79 obj.add_error('name','不能为空!') 80 return ValidationError(#添加错误信息 返回 81 ("%(field)s:该字段 不能为空"), 82 code='invalid', 83 params={'field':'name',}, 84 ) 85 elif len(name)<5: 86 obj.add_error('name','不能小于5个字符!') 87 #return ValidationError('',) 88 return ValidationError(#添加错误信息 返回 89 ("%(field)s:该字段 不能小于5个字符!"), 90 code='invalid', 91 params={'field':'name',}, 92 ) 93 # ————————30PerfectCRM实现King_admin编辑自定义字段验证———————— 94 95 # ————————05PerfectCRM实现King_admin注册功能获取内存———————— 96 # register(models.Customer,CustomerAdmin) 97 # register(models.CourseRecord) 98 site.register(models.Customer,CustomerAdmin) 99 site.register(models.CourseRecord) 100 # ————————05PerfectCRM实现King_admin注册功能获取内存———————— 101 102 # ————————04PerfectCRM实现King_admin注册功能————————
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 # forms.py 2 # ————————19PerfectCRM实现King_admin数据修改———————— 3 from django import forms 4 from crm import models 5 6 # class CustomerModelForm(forms.ModelForm): 7 # class Meta: #调用内置方法 8 # model = models.Customer #获取表名 9 # fields = "__all__" #字段 10 11 def CreateModelForm(request,admin_obj): 12 class Meta: #调用内置方法 13 model = admin_obj.model #获取表名 14 fields = "__all__" #字段 15 # ————————20PerfectCRM实现King_admin数据修改美化———————— 16 # type()就是一个最实用又简单的查看数据类型的方法。type()是一个内建的函数,调用它就能够得到一个反回值,从而知道想要查询的对像类型信息。 17 # dynamic_model_form = type("DynamicModelForm", (forms.ModelForm,), {"Meta": Meta}) #生成modelform的类, 18 # new()方法是在类准备将自身实例化时调用。new()方法始终都是类的静态方法,即使没有被加上静态方法装饰器。 19 def __new__(cls, *args, **kwargs):#重写 函数生成方法 20 # print("base fields",cls.base_fields) 21 # 字段名 #字段数据 22 for field_name, field_obj in cls.base_fields.items(): 23 # print(field_name,dir(field_obj)) 24 field_obj.widget.attrs['class'] = 'form-control' # 前端的样式 25 # field_obj.widget.attrs['maxlength'] = getattr(field_obj,'max_length' ) if hasattr(field_obj,'max_length') \ 26 # else "" 27 # ————————28PerfectCRM实现King_admin编辑限制———————— 28 if field_name in admin_obj.readonly_fields:#如果,在 29 field_obj.widget.attrs['disabled'] = True 30 # ————————28PerfectCRM实现King_admin编辑限制———————— 31 32 return forms.ModelForm.__new__(cls) 33 34 # ————————28PerfectCRM实现King_admin编辑限制———————— 35 def default_clean(self): 36 #给所有的form默认加一个 clean 验证 37 38 # ————————29PerfectCRM实现King_admin编辑自定义限制———————— 39 from django.forms import ValidationError 40 error_list = [] 41 # ————————29PerfectCRM实现King_admin编辑自定义限制———————— 42 43 # ————————30PerfectCRM实现King_admin编辑自定义字段验证———————— 44 if self.instance.id: # 表示为修改表单 45 for field in admin_obj.readonly_fields: # 如果是不可修改的字段 46 # print("readonly",field,self.instance) 47 # field_val_from_db = getattr(self.instance,field)#取数据库中的值 48 field_val_from_db = getattr(self.instance, field) # 取数据库中的值 49 field_val = self.cleaned_data.get(field) # 前端传来的值 50 #print("cleaned data:",self.cleaned_data,)#要验证的表单 51 for field in self.cleaned_data:#单独字段 52 if hasattr(admin_obj,'clean_%s'%field):#是否有该字段的单独验证 53 field_clean_func=getattr(admin_obj,'clean_%s'%field)#获取对应的函数 54 response=field_clean_func(self)# 55 if response: 56 error_list.append(response) 57 if error_list: 58 raise ValidationError(error_list) 59 #response_sol=admin_obj.('clean_%s'%field)(self.cleaned_data) 60 # ————————30PerfectCRM实现King_admin编辑自定义字段验证———————— 61 62 63 print("default clean:",self)#得到整个form数据 64 for field in admin_obj.readonly_fields:#循环获取crm/kingadmin.py里 readonly_fields = ('name','qq',)的数据 65 print("readonly",field,self.instance)#获取到 字段名 ,对象(值) 66 field_val_from_db = getattr(self.instance,field)#获取数据库的值 67 print("cleaned data:", self.cleaned_data)#获取到 前端的值 68 field_val = self.cleaned_data.get(field)#获取到 前端的值 69 70 if field_val_from_db == field_val:#数据库的值和前端的值对比 71 print("数据库数据和前端数据一样 ") 72 else: # 被篡改了 73 self.add_error(field,' "%s" 是一个只读的字段,值应该是 "%s"! 大神请不要篡改!!!'% (field, field_val_from_db)) 74 75 # ————————29PerfectCRM实现King_admin编辑自定义限制———————— 76 response=admin_obj.default_form_validation(self)#可自定制 77 if response: 78 error_list.append(response) 79 if error_list: 80 raise ValidationError(error_list) 81 # ————————29PerfectCRM实现King_admin编辑自定义限制———————— 82 83 # ————————28PerfectCRM实现King_admin编辑限制———————— 84 85 dynamic_model_form = type("DynamicModelForm", (forms.ModelForm,), {"Meta": Meta}) # 生成modelform的类, 86 setattr(dynamic_model_form, "__new__", __new__) 87 # ————————20PerfectCRM实现King_admin数据修改美化———————— 88 89 # ————————28PerfectCRM实现King_admin编辑限制———————— 90 setattr(dynamic_model_form,"clean",default_clean) #给所有的form默认加一个 clean 验证 91 # ————————28PerfectCRM实现King_admin编辑限制————— 92 93 return dynamic_model_form 94 # ————————19PerfectCRM实现King_admin数据修改————————
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 {#table_change.html#} 2 {## ————————19PerfectCRM实现King_admin数据修改————————#} 3 {#{% extends "king_master/king_index.html" %}#} 4 {##} 5 {#{% load kingadmin_tags %}#} 6 {#{% block right-container-content %}#} 7 {##} 8 {# {{ obj_form }}#} 9 {##} 10 {#{% endblock %}#} 11 {## ————————19PerfectCRM实现King_admin数据修改————————#} 12 13 {## ————————20PerfectCRM实现King_admin数据修改美化————————#} 14 {% extends 'king_master/king_index.html' %} {#继承模板#} 15 {% load kingadmin_tags %} {#通过自己定义标签获取中文,Django中利用filter与simple_tag为前端自定义函数的实现方法#} 16 17 18 19 20 {% block right-container-content %} 21 <div class="row" style="margin-bottom: 20px" > 22 <ol class="breadcrumb"> 23 <li><a href="/king_admin/">主页</a></li> 24 <li><a href="/king_admin/{% get_app_name admin_obj.model %}/">{% get_app_name admin_obj.model %}</a></li> 25 <li><a href="/king_admin/{% get_app_name admin_obj.model %}/{% get_model_name admin_obj.model %}/"> 26 {% get_model_verbose_name admin_obj.model%} </a></li> 27 {% if not admin_obj.is_add_form %} {# 新建时 ForeignKey不能实例化 #} 28 <li class="active">{{ obj_form.instance }}</li> {# 修改时 实例化 #} 29 {% endif %} 30 </ol> 31 {## ————————25PerfectCRM实现King_admin添加出错修复————————#} 32 {# <h4>修改:{% get_model_verbose_name admin_obj.model %}</h4>#} 33 34 {% block Tops %} 35 <div class="panel panel-info"> 36 <h4 style='color: red'>修改: {% get_model_verbose_name admin_obj.model %}</h4> 37 </div> 38 {% endblock %} 39 {## ————————25PerfectCRM实现King_admin添加出错修复————————#} 40 </div> 41 42 <div class="row"> 43 {{ obj_form.errors }} 44 45 {## ————————28PerfectCRM实现King_admin编辑限制————————#} 46 {## ————————27PerfectCRM实现King_admin编辑复选框————————#} 47 {#<form class="form-horizontal" method="post" >{% csrf_token %}#} 48 <form class="form-horizontal" method="post" onsubmit="return BeforeFormSubmit(this);">{% csrf_token %} 49 {## ————————27PerfectCRM实现King_admin编辑复选框————————#} 50 {## ————————28PerfectCRM实现King_admin编辑限制————————#} 51 52 {% for field in obj_form %} 53 <div class="form-group"> 54 <label class="col-sm-2 " style="font-weight: normal"> {#字体#} 55 {% if field.field.required %} {#required判断是不是必须填写#} 56 <b>{{ field.label }}</b> 57 {% else %} 58 {{ field.label }} 59 {% endif %} 60 61 </label> 62 <div class="col-sm-10" > 63 <span style="color: red;">{{ field.errors }}</span> 64 65 66 67 {## ————————27PerfectCRM实现King_admin编辑复选框————————#} 68 {# {{ field }}#} 69 {% if field.name in admin_obj.filter_horizontal %} <!-- 水平--><!-- 判断是否复选框--> 70 {% get_m2m_chosen_objs admin_obj field.name obj_form.instance as m2m_chosen_objs %} <!--当前对象已经选中的字段名--> 71 <!-- 左边待选框--> 72 <div class="col-md-6"> 73 <!-- 取所有的内容--> 74 {% get_m2m_available_objs admin_obj field.name as m2m_available_objs %} 75 {# <input type="text" oninput="FuzzSearch(this,'id_{{ field.name }}_from')" class="form-control">#} 76 <!-- 字段名--> 77 <select multiple field_name="{{ field.name }}" class="form-control filter-select-box" id="id_{{ field.name }}_from" > 78 <!-- 字段名 是否为不能修改--> 79 {% if field.name in admin_obj.readonly_fields and not admin_obj.is_add_form %} 80 {% for obj in m2m_available_objs %} 81 {% if obj not in m2m_chosen_objs %}<!--不在当象已经选中的字段名 才显示--> 82 <option value="{{ obj.id }}" disabled>{{ obj }}</option> 83 {% endif %} 84 {% endfor %} 85 {% else %} 86 {% for obj in m2m_available_objs %} 87 {% if obj not in m2m_chosen_objs %}<!--不在当象已经选中的字段名 才显示--> 88 <option value="{{ obj.id }}" ondblclick="MoveEleTo(this,'id_{{ field.name }}_to')">{{ obj }}</option> 89 {% endif %} 90 {% endfor %} 91 {% endif %} 92 </select> 93 </div> 94 <!-- 中间箭头--> 95 <div class="col-md-1"> 96 <div><h4 style='color: #00ff06'>待选 -> </h4></div> 97 <div><h4 style='color: #8dffc5'>双击选择 </h4></div> 98 <div><h4 style='color: #ff0003'> <- 已选 </h4></div> 99 </div> 100 101 <!-- 右边已选框--> 102 <div class="col-md-5"> 103 <select m2m_right="yes" name="{{ field.name }}" multiple field_name="{{ field.name }}" class="form-control" id="id_{{ field.name }}_to"> 104 {% if field.name in admin_obj.readonly_fields and not admin_obj.is_add_form %} 105 {% for obj in m2m_chosen_objs %} 106 <option value="{{ obj.id }}" disabled>{{ obj }}</option> 107 {% endfor %} 108 {% else %} 109 110 {% for obj in m2m_chosen_objs %} 111 <option value="{{ obj.id }}" ondblclick="MoveEleTo(this,'id_{{ field.name }}_from')">{{ obj }}</option> 112 {% endfor %} 113 {% endif %} 114 </select> 115 116 </div> 117 118 {% else %} 119 120 {## ————————30PerfectCRM实现King_admin编辑自定义字段验证————————#} 121 {{ field }} <span style="color: #bce8f1"> {{ field.help_text }}</span> 122 {# <span style="color:red">{{ field.errors }}</span>#} 123 {## ————————30PerfectCRM实现King_admin编辑自定义字段验证————————#} 124 125 126 {% endif %} <!-- 判断是否复选框--> 127 {## ————————27PerfectCRM实现King_admin编辑复选框————————#} 128 129 130 131 </div> 132 </div> 133 {% endfor %} 134 135 {## ————————25PerfectCRM实现King_admin添加出错修复————————#} 136 {## ————————23PerfectCRM实现King_admin数据删除————————#} 137 {# <a class="btn btn-danger" href="{% url 'table_delete' app_name model_name obj_form.instance.id %}">删除</a>#} 138 {## ————————23PerfectCRM实现King_admin数据删除————————#} 139 {# <input type="submit" value="保存" class="pull-right btn btn-info" > {#放右边#} 140 141 <div class="form-group"> 142 {% block del %} 143 <div class="col-sm-2"> 144 <a class="btn btn-danger" href="{% url 'table_delete' app_name model_name obj_form.instance.id %}">删除</a> 145 </div> 146 {% endblock %} 147 <div class="col-sm-10"> 148 <input type="submit" value="保存" class="pull-right btn btn-info"> 149 </div> 150 </div> 151 {## ————————25PerfectCRM实现King_admin添加出错修复————————#} 152 153 </form> 154 </div> 155 156 157 158 159 160 {% endblock %} 161 {## ————————20PerfectCRM实现King_admin数据修改美化————————#}
![](https://files.cnblogs.com/files/ujq3/wxzf.gif)
您的资助是我最大的动力!
金额随意,欢迎来赏!
![](https://files.cnblogs.com/files/ujq3/zfbzf.gif)
如果,您希望更容易地发现我的新博客,不妨点击一下绿色通道的
因为,我的写作热情也离不开您的肯定支持,感谢您的阅读,我是【颜言】!