Django项目:CRM(客户关系管理系统)--39--31PerfectCRM实现King_admin编辑多对多限制

readonly_fields = ('qq', 'consultant','tags',)  # 不可修改

  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 
 51                 # ————————31PerfectCRM实现King_admin编辑多对多限制————————
 52                 if hasattr(field_val_from_db,'select_related'):#多对多
 53                     m2m_objs=getattr(field_val_from_db,'select_related')().select_related()#调用多对多,获取对应的值
 54                     m2m_vals=[i[0] for i in m2m_objs.values_list('id')]#转为列表
 55                     set_m2m_vals=set(m2m_vals)#转集合  交集 数据库
 56 
 57                     # vals_from_frontend=self.cleaned_data.get(field)#前端的值  交集
 58                     # m2m_vals=[i[0] for i in vals_from_frontend.values_list('id')]#转为列表
 59                     # print(vals_from_frontend,'前端的值  交集',m2m_vals)
 60 
 61                     set_m2m_vals_from_frontend=set([i.id for i in self.cleaned_data.get(field)])#前端的值  交集
 62                     from django.utils.translation import ugettext as _  # 国际化
 63                     if set_m2m_vals != set_m2m_vals_from_frontend:
 64                         error_list.append(ValidationError(
 65                             _("%(field)s: 该字段不可修改!"),
 66                                     code='invalid',
 67                                     params={'field':field,}
 68                         ))
 69                         self.add_error(field,"不可修改!")
 70                     continue
 71 
 72                 #field_val = self.cleaned_data.get(field)#前端传来的值
 73                 #print('field_val',type(field_val))
 74                 if field_val_from_db != field_val:
 75                     print("field not change ")#不一致
 76                     error_list.append(ValidationError(#添加错误信息
 77                                     _("该字段%(field)s 不可修改,原值为: %(val)s"),
 78                                     code='invalid',
 79                                     params={'field':field,'val':field_val_from_db}
 80                                 ))
 81 
 82                 # else: # 被篡改了
 83                 #     self.add_error(field,' "%s" is a readonly field ,value should be "%s" '% (field, field_val_from_db))
 84 
 85                 # ————————31PerfectCRM实现King_admin编辑多对多限制————————
 86 
 87         #print("cleaned data:",self.cleaned_data,)#要验证的表单
 88         for field in self.cleaned_data:#单独字段
 89             if hasattr(admin_obj,'clean_%s'%field):#是否有该字段的单独验证
 90                 field_clean_func=getattr(admin_obj,'clean_%s'%field)#获取对应的函数
 91                 response=field_clean_func(self)#
 92                 if response:
 93                     error_list.append(response)
 94                 if error_list:
 95                     raise ValidationError(error_list)
 96                 #response_sol=admin_obj.('clean_%s'%field)(self.cleaned_data)
 97         # ————————30PerfectCRM实现King_admin编辑自定义字段验证————————
 98 
 99 
100         # ————————31PerfectCRM实现King_admin编辑多对多限制————————
101         # print("default clean:",self)#得到整个form数据
102         # for field in admin_obj.readonly_fields:#循环获取crm/kingadmin.py里    readonly_fields = ('name','qq',)的数据
103         #     print("readonly",field,self.instance)#获取到 字段名 ,对象(值)
104         #     field_val_from_db  = getattr(self.instance,field)#获取数据库的值
105         #     print("cleaned data:", self.cleaned_data)#获取到 前端的值
106         #     field_val = self.cleaned_data.get(field)#获取到 前端的值
107         #
108         #     if field_val_from_db == field_val:#数据库的值和前端的值对比
109         #         print("数据库数据和前端数据一样 ")
110         #     else: # 被篡改了
111         #         self.add_error(field,' "%s" 是一个只读的字段,值应该是 "%s"! 大神请不要篡改!!!'% (field, field_val_from_db))
112         # ————————31PerfectCRM实现King_admin编辑多对多限制————————
113 
114 
115         # ————————29PerfectCRM实现King_admin编辑自定义限制————————
116         response=admin_obj.default_form_validation(self)#可自定制
117         if response:
118             error_list.append(response)
119         if error_list:
120             raise ValidationError(error_list)
121         # ————————29PerfectCRM实现King_admin编辑自定义限制————————
122 
123     # ————————28PerfectCRM实现King_admin编辑限制————————
124 
125     dynamic_model_form = type("DynamicModelForm", (forms.ModelForm,), {"Meta": Meta})  # 生成modelform的类,
126     setattr(dynamic_model_form, "__new__", __new__)
127     # ————————20PerfectCRM实现King_admin数据修改美化————————
128 
129     # ————————28PerfectCRM实现King_admin编辑限制————————
130     setattr(dynamic_model_form,"clean",default_clean)  #给所有的form默认加一个 clean  验证
131     # ————————28PerfectCRM实现King_admin编辑限制—————
132 
133     return dynamic_model_form
134 # ————————19PerfectCRM实现King_admin数据修改————————
# forms.py

  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 
 80                                     {## ————————31PerfectCRM实现King_admin编辑多对多限制————————#}
 81                                     {% if field.name in admin_obj.readonly_fields and not admin_obj.is_add_form %}
 82                                         {% for obj in m2m_available_objs  %}
 83                                             {% if obj not in m2m_chosen_objs %}<!--不在当象已经选中的字段名 才显示-->
 84                                                 <option value="{{ obj.id }}" disabled>{{ obj }}</option>
 85                                             {% endif %}
 86                                         {% endfor %}
 87                                     {## ————————31PerfectCRM实现King_admin编辑多对多限制————————#}
 88 
 89                                     {% else %}
 90                                         {% for obj in m2m_available_objs %}
 91                                             {% if obj not in m2m_chosen_objs %}<!--不在当象已经选中的字段名 才显示-->
 92                                                 <option value="{{ obj.id }}" ondblclick="MoveEleTo(this,'id_{{ field.name }}_to')">{{ obj }}</option>
 93                                             {% endif %}
 94                                         {% endfor %}
 95                                     {% endif %}
 96                                 </select>
 97                             </div>
 98                             <!--    中间箭头-->
 99                             <div class="col-md-1">
100                                 <div><h4 style='color: #00ff06'>待选 ->  </h4></div>
101                                 <div><h4 style='color: #8dffc5'>双击选择 </h4></div>
102                                 <div><h4 style='color: #ff0003'> <- 已选 </h4></div>
103                             </div>
104 
105                             <!--    右边已选框-->
106                             <div class="col-md-5">
107                                 <select m2m_right="yes" name="{{ field.name }}" multiple field_name="{{ field.name }}" class="form-control" id="id_{{ field.name }}_to">
108 
109                                     {## ————————31PerfectCRM实现King_admin编辑多对多限制————————#}
110                                     {% if field.name in admin_obj.readonly_fields and not admin_obj.is_add_form %}
111                                         {% for obj in m2m_chosen_objs %}
112                                          <option value="{{ obj.id }}" disabled>{{ obj }}</option>
113                                         {% endfor %}
114 
115                                      {## ————————31PerfectCRM实现King_admin编辑多对多限制————————#}
116                                     {% else %}
117 
118                                         {% for obj in m2m_chosen_objs %}
119                                             <option value="{{ obj.id }}" ondblclick="MoveEleTo(this,'id_{{ field.name }}_from')">{{ obj }}</option>
120                                         {% endfor %}
121                                     {% endif %}
122                                 </select>
123 
124                             </div>
125 
126                         {% else %}
127 
128                             {## ————————30PerfectCRM实现King_admin编辑自定义字段验证————————#}
129                             {{ field }} <span style="color: #bce8f1"> {{ field.help_text }}</span>
130 {#                            <span style="color:red">{{ field.errors }}</span>#}
131                             {## ————————30PerfectCRM实现King_admin编辑自定义字段验证————————#}
132 
133 
134                         {% endif %} <!--     判断是否复选框-->
135                         {## ————————27PerfectCRM实现King_admin编辑复选框————————#}
136 
137 
138 
139                     </div>
140                   </div>
141             {% endfor %}
142 
143             {## ————————25PerfectCRM实现King_admin添加出错修复————————#}
144             {## ————————23PerfectCRM实现King_admin数据删除————————#}
145 {#            <a class="btn btn-danger" href="{% url 'table_delete' app_name model_name obj_form.instance.id %}">删除</a>#}
146            {## ————————23PerfectCRM实现King_admin数据删除————————#}
147 {#            <input type="submit" value="保存" class="pull-right btn btn-info" >   {#放右边#}
148 
149             <div class="form-group">
150                 {% block del %}
151                     <div class="col-sm-2">
152                         <a class="btn btn-danger" href="{% url 'table_delete' app_name model_name obj_form.instance.id %}">删除</a>
153                     </div>
154                 {% endblock %}
155                 <div class="col-sm-10">
156                     <input type="submit" value="保存" class="pull-right btn btn-info">
157                 </div>
158             </div>
159             {## ————————25PerfectCRM实现King_admin添加出错修复————————#}
160 
161         </form>
162    </div>
163 
164 
165 
166     
167 
168 {% endblock %}
169 {## ————————20PerfectCRM实现King_admin数据修改美化————————#}
{#table_change.html#}


原文地址:https://www.cnblogs.com/ujq3/p/8711292.html