CRM readonly、Form and field validation——第27天

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

 

 

 

 

 

 

 

 

 

 

posted @ 2019-08-20 22:27  智、心  阅读(212)  评论(0编辑  收藏  举报