zoukankan      html  css  js  c++  java
  • 用户提交数据的验证

    一,原始方法的缺陷:

    1,用  request.POST.get('变量名') 的方法获取信息,操作重复。

    2,没有错误信息的提示

    3,没保留上一次提交的数据

    二,用户提交数据验证

    长度,类型,格式

    重用性(多次用到密码,用户名,邮箱等的验证,同一个网站要用相同的验证方法)

    解决方法:用一个类实现。

    from django import forms
    #模板
    class LoginForm(forms.Form):
        #模板中的元素
    
        user=forms.CharField(min_length=6,erroe_message={"required":"用户名不能为空","min_length":'长度输入不够'})
        #user变量名要与前端的form表单的名称对应一致
    
        email=forms.EmailField(error_message={"required":"邮箱不能为空","invaild":"邮箱格式错误"})    #根据错误信息自定义,提示信息。
    
       
    def login(request):
        if request.method=='GET':
            retrun render(request,'login.html')
        elif request.method=='POST':
            obj=LoginForm(request.POST)
            #实例对象
            #验证is_vaild会返回获取的变量与模板的要求是否匹配,返回boolean
            if obj.is_valid():
        #返回.clean返回验证正确的值,用字典的方式
                value_dict=obj.clean()
            else:
                error_obj=obj.errors.as_json()#获取错误信息,转换为json格式
            return render(request,'login.html')

     三,当有一个数据输入错误时,其他的信息不会清空,会保留。

    1,创建模板              class LoginForm(forms.Form):....

    2,将请求交给模板,创建一个对象    obj=LoginForm(request.POST)

    3,进行验证              obj.is_valid()

    4,获取正确信息            obj.clean()

    5,获取错误信息            obj.errors

    <!DOCTYPE html>
    <html>
        <head>
            <meta charset="UTF-8">
            <title>Form自动验证</title>
        </head>
        <body>
            <h1>form提交数据</h1>
            <form method="post" action="/login.html">
                <p>
                    {{oo.user}}
    //自动的返回html代码,并且会保存上一次的数据
    <span>{{oo.errors.user.0}}</span> </p> <p> {{oo.email}} <span>{{oo.errors.email.0}}</span> </p> <p> <input type="text" name="pwd" placeholder="密码" /> </p> <input type="submit" value="提交" /> </form> </body> </html>

    处理函数

    处理函数
    def login(request):
        if request.method=='GET':
            obj=LoginForm()
            return render(request,'login.html',{'oo':obj})
        elif request.method=='POST':
            obj=LoginForm(request.POST)
            if obj.is_valid():
                value_dict=obj.clean()
            else:
                error_obj=obj.errors
                #error_obj['email'][0]是对应错误信息的sstring
            return render(request,'login.html',{'oo':obj,'value_dict':value_dict,'errors':error_obj})

     四,Ajax提交的两种方法

    def login_ajax(request):
        if request.method=='GET':
            obj=LoginForm()
            return render(request,'login_ajax.html')
        elif request.method=='POST':
            ret={'status':True,'error':None,'data':None}
            obj=LoginForm(request.POST)
            if obj.is_valid():
                value_dict=obj.clean()
            else:
                #方式一
                res_str=obj.errors.as_json()#res_str是一个字符串
                ret['erroe']=res_str
                ret['status']=False
                #方式二
                ret['status']=False
                ret['erroe']=obj.errors.as_data();
                #{'user':{ValidationError(['用户名长度不能小于6'])},'email':{ValidationError(['邮箱不能为空'])}}
            return HttpResponse(json.dump(ret,cls=JsonCustomEncoder))

    五,用户验证的参数

    1,Django的Form的实现步骤

      a ,创建一个验证用户的请求的模板

      form django import forms

      class MyForm(forms.Form):

        user=field.CharField(widget=widgets.TextInput(attrs={'class':'c1','placeholder':'用户名'}))

      类:模板的验证类型设置

      字段:用于验证用户的某个字段

      插件:user=forms.CharField(...,widget=Input框)

      设置不同的插件类型,可以实现用户输入的信息进行转换。

    b,获取用户的请求,进行验证

      is_valid()//该步骤必须要写,开始验证

      clean()  获取正确的返回结果

      errors错误信息

    c,Form提交:

        errors.字段.0

      ajax提交:

        errors.as_json()

        errors.as_data()

    2,在html的用应用

    <!DOCTYPE html>
    <html lang="zh">
    <head>
        <meta charset="UTF-8" />
        <meta name="viewport" content="width=device-width, initial-scale=1.0" />
        <meta http-equiv="X-UA-Compatible" content="ie=edge" />
        <title>Document</title>
    </head>
    <body>
        <form method="post" action="/field.html">
            <label for="{{obj.user.id_for_label}}">{{obj.user.label}}</label>
            {{obj.user.label_tag}}//与上一排的代码等效,相当于点击文字后input有光标,后台代码,设置了label的属性
            {{obj.user}}
            <input type="submit" value="提交" />
        </form>
    </body>
    </html>

    后台:

    #后台代码:
    class FieldForm(forms.Form):
        user=fiels.CharField(
        required=False,
        initial='小虎',
        validators=[RegexValidator(r'^[0~9]+$','1111',code='f1'),RegexValidator(r'^158[0~9]+$','2222',code='f2')],
        error_messages={'required':'不能为空','f1':'f1格式错误','f2':'数字的格式不对'},
        #错误信息的优先级是error_messages大于validators,error_messages中的f1是于validators中的code参数一致的。
        #错误信息格式:{"user":"[{"message":"f1格式错误","code":"f1"},{"message":"数字的格式不对","code":"f2"}]"} 

      show_hidden_initial
    =True label='用户名' )

     五,总结

    forms与modelform的基类都是BaseForm

    以下是字段的用处

    class user(models.Model):

      u=字段()

    a,admin中验证

    b,object.clean_fields()

    from django.core.handlers.wsgi import WSGIRequest
        
    def test(request):
        #获取请求头信息
        #request.environ
        #获取请求头信息中的访问端的机器型号
        #request.environ.get('HTTP_USER_AGENT')
        
        obj=models.Test(name='root',email='213')
        obj.clean_fields()
        #开始验证
        obj.save()
        return render(request,'test.html')

    c,

      1,form组件验证

        name,email

      2,model组件操作数据

        name, email

      3,modelForm

        数据与验证放在一起,耦合太紧了,在django的admin中使用,其余建议分开写

        ModelForm组件验证

          用户model中的字段

        model组件操作数据

          name, email

    class UserInfoForm(forms.ModelForm):
        username=forms.CharField(error_message= {'required':"用户名不能为空"})
        email=forms.EmailField(error_message= {'invalid':'邮箱格式错误'})
        age=forms.IntergeField(inital=1,error_message={'required':'请输入数值'})
        
        class Meta:
            model=models.UserInfo
            fields="_all_"
    class News(models.Model):
        title=models.CharField(max_length=64)
        summary=models.CharField(max_length=128,null=True)
        url=models.URLField(null=True)
        ctime=models.DateTimeField(auto_now_add=True)
        user=models.ForeignKey(to="UserInfo",to_field='nid')//UserInfo是用户信息表
        favor=models.ManyToManyField('User',through='Favor',through_field=('news','user'))
        #manytoMany在admin中管理字段时会有一个下拉框,through是对应的表,through——field是对应的字段
        news_type_choices=[
        (1,'42区'),
        (2,'段子'),
        (3,'图片'),
        (4,'你问我答'),
        //由于有固定的类型,可以直接用列表的形式存放
        
        ]
        nt=models.IntegerField(choices=news_type_choices)
        favor_count=models.IntegerField(default=0)
        
    #关联的第三张表
    class Favor(models.Model):
        new=models.ForeignKey('News')
        user=models.ForeignKey('User')

    验证的顺序是先modelForm再form

    六,form验证补充,自定义验证

    obj.is_valid()
    原码执行顺序:
    循环form对象中的所有字段,
    for name,field_obj in xx.item
    去用户请求中获取数据
    1,调用字段的clean方法,进行正则表达式的验证
      field_obj.clean(value)
      self.clean_[name]() #name是字段名,self是form对象
    2,self.clean()
    3,_post_clean()

    form补充
    class UserForm(forms.Form):
        username=fields.CharField(label="用户名")
        email=fields.EmailField(label="邮箱")
        
        #分字段自定义验证
        def clean_username(self):
        #self是form对象
            value=self.cleaned_data['username']#返回的数据都是放在cleaned_data中
            if value=='root':
                return value
            else:
                raise ValidationError('验证错误')
                #抛出异常,会被try捕获
        #总体验证,可以抛出异常
        def clean(self):
            v1=self.cleaned_data['username']
            v2=self.cleaned_data['email']
            if v1=='root' and v2=='root@live.com':
                pass
            else:
                raise ValidationError('用户名或邮箱错误')
            return self.cleaned_data
        
        def _post_clean(self):
            v1=self.cleaned_data['username']
            v2=self.cleaned_data['email']
            if v1=='root' and v2=='root@live.com':
                pass
            else:
                self.add_error("__all__",ValidationError('用户名或邮箱错误'))#'__all__'可以用‘None’代替
            return self.cleaned_data

     七,补充

    #连表操作的补充
    循环读取数据,多次访问数据库
    select_related
    主动做连表操作,一次访问数据库表。
    select * from user as tb left join user_type on tb.xx=tb1.xx

    prefetch_related
    select * from user
    #用户类型id
    selsct * from user_type where id in 用户类型id


    model:http://www.cnblogs.com/wupeiqi/articles/6216618.html
    form :http://www.cnblogs.com/wupeiqi/articles/6144178.html
    modelform:http://www.cnblogs.com/wupeiqi/articles/6229414.html

    参照:www.cnblogs.com/wupeiqi/articles/6144178.html

  • 相关阅读:
    Java I/O的典型使用方式
    搜索--hiho 骑士问题
    编程之美--水王(找出出现超过1/2的数)
    深入理解java虚拟机之类文件结构以及加载
    【转载】Java JVM 运行机制及基本原理
    整数的划分总结(转)
    java静态方法和非静态方法
    mongodb 运行错误总结
    MongoDb windows环境安装,附百度云链接
    JAVA解析Json数据
  • 原文地址:https://www.cnblogs.com/gjx1212/p/13739920.html
Copyright © 2011-2022 走看看