用户提交数据的验证

一,原始方法的缺陷:

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

posted on 2020-09-27 15:42  居一雪  阅读(291)  评论(0编辑  收藏  举报

导航