#在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 ValidationError
from 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