zoukankan      html  css  js  c++  java
  • 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

     

  • 相关阅读:
    AJAX异步传输——以php文件传输为例
    js控制json生成菜单——自制菜单(一)
    vs2010中关于HTML控件与服务器控件分别和js函数混合使用的问题
    SQL数据库连接到服务器出错——无法连接到XXX
    PHP错误:Namespace declaration statement has to be the very first statement in the script
    【LeetCode】19. Remove Nth Node From End of List
    【LeetCode】14. Longest Common Prefix
    【LeetCode】38. Count and Say
    【LeetCode】242. Valid Anagram
    【LeetCode】387. First Unique Character in a String
  • 原文地址:https://www.cnblogs.com/venvive/p/11386072.html
Copyright © 2011-2022 走看看