查看: 490|回复: 0

[PHP学习] Python中使用django form表单验证的方法

发表于 2017-11-25 09:39:57
句号论坛

一. django form表单验证引入  

有时时候我们需要使用get,post,put等方式在前台HTML页面提交一些数据到后台处理例 ;

  1. <!DOCTYPE html>
  2. <html lang="en">
  3. <head>
  4. <meta charset="UTF-8">
  5. <title>Form</title>
  6. </head>
  7. <body>
  8. <div>
  9. <form action="url" method="post" enctype="multipart/form-data">{% csrf_token %}
  10. <input type="text" name="username"/>
  11. <input type="password" name="password"/>
  12. <input type="submit" value="submit"/>
  13. </form>
  14. </div>
  15. </body>
复制代码

前端提交后台获取:

  1. from django.shortcuts import render,HttpResponse,redirect
  2. from app01 import models
  3. def Login(request):
  4. if request.method == "POST":
  5. username = request.POST.get("username")
  6. password = request.POST.get("password")
  7. return HttpResponse("Hello,%s"%(username))
复制代码

这样就完成了基本的功能,基本上可以用了。

但是,如果用户输入并未按照要求(比如手机号要输数据11位长度,密码的复杂度等),还有就是提交后再回来已经输入的数据也会没了

当然如果我们手动将输入之后的数据在 views 中都获取到再传递到网页,这样是可行的,但是很不方便,所以 Django 提供了更简单易用的 forms 来解决验证等这一系列的问题

,在这里不得不提Django的插件库真的很强大,简单易扩展,上面的内容只是引进为什么要使用form,下面着重记录django form的使用

二.form表单验证应用

  需要在django的APP中新建一个模块form.py,具体内容如下

  1. class RegisterForm(forms.Form):
  2. email = forms.EmailField(required=True,
  3. error_messages={'required': "邮箱不能为空"})
  4. password = forms.CharField(max_length=120,
  5. min_length=6,
  6. required=True,
  7. error_messages={'required': "密码不能为空"})
  8. invite_code = forms.CharField(required=True,error_messages={'required': "验证码不能为空"})
复制代码

前端页面

  1. <!DOCTYPE html>
  2. <html lang="en">
  3. <head>
  4. <meta charset="UTF-8">
  5. <title>register</title>
  6. </head>
  7. <body>
  8. <div>
  9. <form action="url" method="post" enctype="multipart/form-data">
  10. <input type="text" name="username"/>
  11. <input type="password" name="password"/>
  12. <input type="text" name="code"/>
  13. <input type="submit" value="submit"/>
  14. </form>
  15. </div>
  16. </body>
复制代码

后台views处理

  1. def register(request):
  2. if request.method == "POST":
  3. f = Reg_Form(request.POST)
  4. if f.is_valid():
  5. user = f.cleaned_data["username"]
  6. pwd = f.cleaned_data["password"]
  7. code = f.cleaned_data["code"]
  8. res_code = request.session.get("code", None)
  9. result = models.UserInfo.objects.filter(user__exact=user,pwd__exact=pwd)
  10. if code.upper() == res_code.upper() and result:
  11. models.UserInfo.objects.filter(user__exact=user).update(status=1)
  12. request.session["user"] = user
  13. return redirect("/home")
  14. else:
  15. return render(request, "register.html", {"error": f.errors, "form": f})else:return render(request, "register.html")
复制代码

Reg_Form(request.POST) 使用form类来处理提交的数据来验证数据的合法性,is_valid()合法后的逻辑处理,验证后的数据保存在实例化后返回的cleaned_data中,

cleaned_data是个字典的数据格式,错误信息保存在form.errors中比如说想在views中查看所有报错信息print(f.errors),如果只想看用户的可以

  1. print(form.errors['username'][0])
复制代码

错误信息我们可以通过 模板渲染回前端页面,例

  1. <form action="/form/" method="POST">
  2. {% csrf_token %}
  3. <div class="input-group">
  4. {#接收后台传过来的form对象,自动生成input标签#}
  5. {{ form.user }}
  6. {#从后台传过来的error是字典,直接{{ error.user.0 }}呈现错误信息#}
  7.        {#如果后台返回了错误信息,将错误信息放入span标签,在页面显示,否则不显示#}
  8. {% if error.username.0 %}
  9. <span>{{ error.userusername.0 }}</span>
  10. {% endif %}
  11. </div>
  12. <div class="input-group">
  13. {{ form.password }}
  14. {% if error.pwd.0 %}
  15. <span>{{ error.password .0 }}</span>
  16. {% endif %}
  17. </div>
  18. <div>
  19. <input type="submit" value="提交" />
  20. </div>
  21. </form>
复制代码

三.自生成input框

Form类

  1. class RegisterForm(forms.Form):
  2. style = 'form-control input-lg'
  3. phone = forms.CharField(widget=forms.TextInput(attrs={'class': style,
  4. 'name': 'title'})),
  5. required=True,
  6. error_messages={'required': ugettext_lazy('*Required')})
  7. code = forms.CharField(widget=forms.NumberInput(attrs={'placeholder': '验证码',
  8. 'class': style}),
  9. min_length=4,
  10. max_length=4,
  11. required=True,
  12. error_messages={'required': ugettext_lazy('*Required')})
  13. password = forms.CharField(widget=forms.PasswordInput(attrs={'placeholder': '请输入密码',
  14. 'class': style}),
  15. min_length=6,
  16. required=True,
  17. error_messages={'required': ugettext_lazy('*Required')})
复制代码

views

  1. def register(request):
  2. if request.method == "POST":
  3. f = RegisterForm(request.POST)
  4. if f.is_valid():
  5. user = f.cleaned_data["username"]
  6. pwd = f.cleaned_data["password"]
  7. code = f.cleaned_data["code"]
  8. res_code = request.session.get("CheckCode", None)
  9. result = models.UserInfo.objects.filter(user__exact=user,pwd__exact=pwd)
  10. if code.upper() == res_code.upper() and result:
  11. models.UserInfo.objects.filter(user__exact=user).update(status=1)
  12. request.session["user"] = user
  13. return redirect("/home")
  14. else:
  15. return render(request, "login.html", {"error": f.errors, "form": f})
  16. else:
  17. return render(request, "login.html", {"error": f.errors, "form": f})
  18. else:
  19.     # 如果不是post提交数据,就不传参数创建对象,并将对象返回给前台,直接生成input标签,内容为空
  20. f = Log_Form()
  21. return render(request, "login.html", {"form": f})
复制代码

前端页面

  1. <body>
  2. <form action="/form/" method="POST">
  3.   {% csrf_token %}
  4. <div class="input-group">
  5. {# 接收后台传过来的form对象,自动生成input标签#}
  6. {{ form.user }}
  7. {# 从后台传过来的error是字典,直接{{ error.user.0 }}呈现错误信息#}
  8. {# 如果后台返回了错误信息,将错误信息放入span标签,在页面显示,否则不显示#}
  9. <div class="input-group">
  10. {{ form.email }}
  11. {% if error.email.0 %}
  12. <span>{{ error.email.0 }}</span>
  13. {% endif %}
  14. </div>
  15. <div class="input-group">
  16. {{ form.password }}
  17. {% if error.password.0 %}
  18. <span>{{ error.password.0 }}</span>
  19. {% endif %}
  20. </div>
  21. <div class="input-group">
  22. {{ form.code }}
  23. {% if error.book_type.0 %}
  24. <span>{{ error.code.0 }}</span>
  25. {% endif %}
  26. </div>
  27. <div>
  28. <input type="submit" value="提交" />
  29. </div>
  30. </form>
  31. </body>
  32. </html>
复制代码

四.Form验证完善

https://docs.djangoproject.com/en/dev/ref/forms/validation/

form验证的运行顺序是init,clean,validte,save

其中clean和validate会在form.is_valid()方法中被先后调用

clean等步骤遇到的异常:Exception Value: argument of type 'NoneType' is not iterable.

可能是cleaned_data中某个字段值应该是个列表,实际上却是空值。

clean方法重写时一定不要忘了return cleaned_data

这样重写可以使用户提交的数据在form类中执行检测完后返回数据给用户,数据合法后进行逻辑处理,不需要再进行处理返回用户,更方便更合理

补充:

5.form的四种初始化方式

①实例化oneform(initial={'onefield':value})

②定义字段时给初始化值oneformfield = forms.CharField(initial=value)

③重写Form类的__init__()方法:self.fields['onefield'].initial = value

④当给form传参instanse(即oneform(instanse=onemodel_instance))时,前三种初始化方法会全部失效,即使重写__init__时,先调用父类的__init__再使用方法③,仍然无效(不是很爽)。

这时想重新初始化字段值只能在__init__()里 self.initial['title'] = value,直接对Form类的initial属性字典赋值。

  1. from django import forms
  2. class RegisterForm(forms.Form):
  3. email = forms.EmailField(required=True,
  4. error_messages={'required': "邮箱不能为空"})
  5. password = forms.CharField(max_length=120,
  6. min_length=6,
  7. required=True,
  8. error_messages={'required': "密码不能为空"})
  9. invite_code = forms.CharField(required=True,error_messages={'required': "验证码不能为空"})
  10. def clean(self):
  11. # 用户名
  12. try:
  13. email = self.cleaned_data['email']
  14. except Exception as e:
  15. raise forms.ValidationError(u"注册账号需为邮箱格式")
  16. # 验证邮箱
  17. user = User.objects.filter(username=email)
  18. if user: # 邮箱已经被注册了
  19. raise forms.ValidationError(u"邮箱已被注册")
  20. # 密码
  21. try:
  22. password = self.cleaned_data['password']
  23. except Exception as e:
  24. print('except: ' + str(e))
  25. raise forms.ValidationError(u"请输入至少6位密码")
  26. return self.cleaned_data
复制代码

以上所述是小编给大家介绍的Python中使用django form表单验证的方法,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对程序员之家网站的支持!



太阳http代理AD
回复

使用道具 举报

关闭

站长推荐上一条 /1 下一条