#在kind_admin.py文件中加上readonly_fields代表里面的字段是可读readonly_fields = ['qq','consultant']
2、在form.py文件中给可读字段加上disabled属性,因为readonly属性对于下拉框可读是不起作用的:
#form.py def creat_model_form(request,admin_class): def __new__(cls,*args,**kwargs): #super(CustomerForm,self).__new__(*args,**kwargs) # print("base fields",cls.base_fields) for field_name,field_obj in cls.base_fields.items(): print(field_name,dir(field_obj)) field_obj.widget.attrs['class'] = 'form-control' field_obj.widget.attrs['maxlength'] = getattr(field_obj,'max_length')if hasattr(field_obj,"max_length") else '' #判断表单字段如果是可读那就在前端加上disabled属性 if field_name in admin_class.readonly_fields: field_obj.widget.attrs["disabled"] = "disabled" return ModelForm.__new__(cls)
3、disable属性当前端提交的时候具有disable的数据是不当作请求数据传给后端的,为了解决这个会在请求的时候用js把disabled这个属性清除掉,代码如下:
#table_objs_change.html function SelectAllChosenData() { $("select[tag='chosen_list'] option").each(function () { $(this).prop("selected",true); }) //在提交的时候把disabled属性删除,这样只读的数据也能够提交给后台 $("form").find("[disabled]").removeAttr("disabled"); //remove all disabled attrs return true; }
4、数据只是可读只是在前端展示禁止修改,但是可以用google检查直接修改数据,所以不仅是需要前端的限制,在后端也是要的(从之前存了数据库中的数据和请求过来的数据作比较(可读字段的数据)),使用了表单的'clean'函数,表单的self.cleaned_data(field)获取前端请求过来的字段值,ValidationError,ugettext抛出请求过来可读的数据和数据库中数据不一致的错误,当有很多错误的时候可以都添加到一个list一起输出,form.py:
from django.forms import ValidationErrorfrom django.utils.translation import ugettext as _
def creat_model_form(request,admin_class): def __new__(cls,*args,**kwargs): #super(CustomerForm,self).__new__(*args,**kwargs) # print("base fields",cls.base_fields) for field_name,field_obj in cls.base_fields.items(): print(field_name,dir(field_obj)) field_obj.widget.attrs['class'] = 'form-control' field_obj.widget.attrs['maxlength'] = getattr(field_obj,'max_length')if hasattr(field_obj,"max_length") else '' #判断表单字段如果是可读那就在前端加上disabled属性 if field_name in admin_class.readonly_fields: field_obj.widget.attrs["disabled"] = "disabled" return ModelForm.__new__(cls) def defauct_clean(self): #from_web_data = request.POST list_error=[] for field in admin_class.readonly_fields: #在表单可读在数据库里的数据 from_db_data = getattr(self.instance,field) #获取前端请求的数据 from_web_data = self.cleaned_data.get(field) print("form_db_data:",field,from_db_data,from_web_data) if from_db_data!= from_web_data: list_error.append(ValidationError( _('Field %(field)s is readonly data should be %(value)s'), code='invalid', params={'field': field,'value':from_db_data} )) if list_error: raise ValidationError(list_error) class Meta: model = admin_class.model fields = "__all__" attr = {"Meta":Meta} _model_form_class = type("DynamicModelForm",(ModelForm,),attr) setattr(_model_form_class,'__new__',__new__) setattr(_model_form_class,'clean',defauct_clean) return _model_form_class
5、在form.py校验表单的,用户也可自己定义校验在表单校验执行结束后执行,在kind_admin.py文件中,比如咨询的文字不能<15个:
from django.forms import ValidationError from django.utils.translation import ugettext as _ #kind_admin.py #在Customer类中加上函数 def default_form_validation(self): content = self.cleaned_data.get("content","") if len(content)<15: return ValidationError( _('Field %(content)s length be >15'), code='invalid', params={'content': 'content'},)
在form.py文件中调用这个函数:
#放在上面的default函数里面 if hasattr(admin_class,'default_form_validation'): default_form_error_info =admin_class.default_form_validation(self) list_error.append(default_form_error_info)
def creat_model_form(request,admin_class): def __new__(cls,*args,**kwargs): #super(CustomerForm,self).__new__(*args,**kwargs) # print("base fields",cls.base_fields) for field_name,field_obj in cls.base_fields.items(): print(field_name,dir(field_obj)) field_obj.widget.attrs['class'] = 'form-control' field_obj.widget.attrs['maxlength'] = getattr(field_obj,'max_length')if hasattr(field_obj,"max_length") else '' #判断表单字段如果是可读那就在前端加上disabled属性 if field_name in admin_class.readonly_fields: field_obj.widget.attrs["disabled"] = "disabled" return ModelForm.__new__(cls) def defauct_clean(self): #from_web_data = request.POST list_error=[] for field in admin_class.readonly_fields: #在表单可读在数据库里的数据 from_db_data = getattr(self.instance,field) #获取前端请求的数据 from_web_data = self.cleaned_data.get(field) print("form_db_data:",field,from_db_data,from_web_data) if from_db_data!= from_web_data: list_error.append(ValidationError( _('Field %(field)s is readonly data should be %(value)s'), code='invalid', params={'field': field,'value':from_db_data} )) if hasattr(admin_class,'default_form_validation'): default_form_error_info =admin_class.default_form_validation(self) list_error.append(default_form_error_info) if list_error: raise ValidationError(list_error) class Meta: model = admin_class.model fields = "__all__" attr = {"Meta":Meta} _model_form_class = type("DynamicModelForm",(ModelForm,),attr) setattr(_model_form_class,'__new__',__new__) setattr(_model_form_class,'clean',defauct_clean) return _model_form_class