Django基础之form操作
Form表单的功能
- 自动生成HTML表单元素
- 检查表单数据的合法性
- 如果验证错误,重新显示表单(数据不会重置)
- 数据类型转换(字符类型的数据转换成相应的Python类型)
Form相关的对象包括
- Widget:用来渲染成HTML元素的工具,如:forms.Textarea对应HTML中的<textarea>标签
- Field:Form对象中的一个字段,如:EmailField表示email字段,如果这个字段不是有效的email格式,就会产生错误。
- Form:一系列Field对象的集合,负责验证和显示HTML元素
- Form Media:用来渲染表单的CSS和JavaScript资源。
Form案例验证
前端:form表单
后台:创建form类,当请求到来时,先匹配,匹配出正确和错误信息。
案例一:
views.py
1 #coding:utf8 2 from django.shortcuts import render,HttpResponseRedirect 3 from app02 import forms,models 4 5 # Create your views here. 6 def form1(request): 7 if request.method=="POST": #这里POST一定要大写 8 #获取请求内容,做验证 9 f = forms.UserMessage(request.POST) #request.POST:将接收到的数据通过forms.UserMessage验证 10 if f.is_valid(): #验证请求的内容和forms.UserMessage里面的是否验证通过。通过是True,否则False。 11 print(f.cleaned_data) #cleaned_data类型是字典,里面是提交成功后的信息 12 else: #错误信息包含是否为空,或者符合正则表达式的规则 13 print(type(f.errors),f.errors) #errors类型是ErrorDict,里面是ul,li标签 14 return render(request,"app02/form1.html",{"error":f.errors}) 15 return render(request,"app02/form1.html")
form1.html
1 <!DOCTYPE html> 2 <html> 3 <head> 4 <meta charset="UTF-8"> 5 <title>基础版</title> 6 </head> 7 <body> 8 <!--{#{{ error }}接收后台返回的错误信息封装在ul,li标签里面:#} --> 9 {{ error }} 10 <form action="/app02/form1/" method="POST"> 11 <div> 12 用户名:<input type="text" name="username" /> 13 </div> 14 <div> 15 密 码:<input type="text" name="password" /> 16 </div> 17 <div> 18 <input type="submit" value="提交" /> 19 </div> 20 </form> 21 </body> 22 </html>
forms.py
#coding:UTF8 from django import forms from app02 import models class UserMessage(forms.Form): UserName = forms.CharField(max_length=100,label='用户名') Password = forms.CharField(max_length=100,label='密码')
访问页面:
没有输入内容后提交,通过模板语言展示了错误信息
form验证时不用自定义错误信息就可以返回错误信息到前端以标签方式展现。
.is_valid():返回True或者False
.cleaned_data:通过验证后的数据
errors:
.error.get("user",None)error封装所有的错误信息,如果没有获取到,默认为None。
.error.get["pwd"]直接获取到ul、li。
如下:
(<class 'django.forms.utils.ErrorDict'>, {'UserName': [u'This field is required.'], 'Password': [u'This field is required.']})
案例二:
views.py
1 #coding:utf8 2 from django.shortcuts import render,HttpResponseRedirect 3 from app02 import forms,models 4 5 def form2(request): 6 if request.method == "POST": 7 f = forms.UserMessage(request.POST) 8 if f.is_valid(): 9 print(f.cleaned_data) 10 else: 11 return render(request,"app02/form2.html",{"error":f.errors,"form":f}) 12 else: 13 # 如果不是post提交数据,就不传参数创建对象,并将对象返回给前台,直接生成input标签,内容为空 14 f = forms.UserMessage() 15 return render(request,"app02/form2.html",{"form":f}) 16 return render(request,"app02/form2.html")
form2.html
1 <!DOCTYPE html> 2 <html> 3 <head> 4 <meta charset="UTF-8"> 5 <title>进阶版</title> 6 <style> 7 .input-group{ 8 position: relative; 9 padding: 20px; 10 width: 250px; 11 } 12 .input-group input{ 13 width: 200px; 14 display: inline-block; 15 } 16 </style> 17 </head> 18 <body> 19 <form action="/app02/form2/" method="POST"> 20 <div class="input-group">用户名: 21 <!-- {#接收后台传过来的form对象,自动生成input标签#}--> 22 {{ form.UserName }} 23 <!-- {#从后台传过来的error是字典,直接{{ error.UserName.0 }}呈现错误信息#} --> 24 <!-- {#如果后台返回了错误信息,将错误信息放入span标签,在页面显示,否则不显示#}--> 25 {% if error.UserName.0 %} 26 <span>{{ error.UserName.0 }}</span> 27 {% endif %} 28 </div> 29 <div class="input-group">密码: 30 {{ form.Password }} 31 {% if error.Password.0 %} 32 <span>{{ error.Password.0 }}</span> 33 {% endif %} 34 </div> 35 <div> 36 <input type="submit" value="提交" /> 37 </div> 38 </form> 39 </body> 40 </html>
forms.py
1 #coding:UTF8 2 from django import forms 3 from app02 import models 4 class UserMessage(forms.Form): 5 UserName = forms.CharField(max_length=100,label='用户名') 6 Password = forms.CharField(max_length=100,label='密码')
案例三:
models.py
1 #coding:Utf8 2 from __future__ import unicode_literals 3 4 from django.db import models 5 from django import forms 6 7 # Create your models here. 8 class Author(models.Model): 9 #作者 10 name = models.CharField(max_length=100) 11 age = models.IntegerField() 12 13 class BookType(models.Model): 14 #图书类型 15 caption = models.CharField(max_length=64) 16 17 class Book(models.Model): 18 #图书 19 name = models.CharField(max_length=64) 20 pages = models.IntegerField() 21 price = models.DecimalField(max_digits=10,decimal_places=2) 22 pubdate = models.DateField() 23 24 authors = models.ManyToManyField(Author) 25 book_type = models.ForeignKey(BookType)
views.py
1 #coding:utf8 2 from django.shortcuts import render,HttpResponseRedirect 3 from app02 import forms,models 4 5 def form3(request): 6 if request.method == "POST": 7 f = forms.Form3(request.POST) 8 if f.is_valid(): 9 print(f.cleaned_data) 10 else: 11 return render(request,"app02/form3.html",{"error":f.errors,"form":f}) 12 else: 13 # 如果不是post提交数据,就不传参数创建对象,并将对象返回给前台,直接生成input标签,内容为空 14 f = forms.Form3() 15 return render(request,"app02/form3.html",{"form":f}) 16 return render(request,"app02/form3.html")
form3.html
1 <!DOCTYPE html> 2 <html> 3 <head> 4 <meta charset="UTF-8"> 5 <style> 6 .input-group{ 7 position: relative; 8 padding: 20px; 9 width: 250px; 10 } 11 .input-group input{ 12 width: 200px; 13 display: inline-block; 14 } 15 .inline-group span{ 16 display: inline-block; 17 position: absolute; 18 height: 12px; 19 font-size: 8px; 20 border: 1px solid red; 21 background-color: coral; 22 color: white; 23 top: 41px; 24 left: 20px; 25 width: 202px; 26 } 27 </style> 28 <title>高级版</title> 29 </head> 30 <body> 31 <form action="/app02/form3/" method="POST"> 32 <div class="input-group"> 33 <!--{#接收后台传过来的form对象,自动生成input标签#} --> 34 用户名:{{ form.UserName }} 35 <!--{#从后台传过来的error是字典,直接{{ error.user.0 }}呈现错误信息#} --> 36 <!--{#如果后台返回了错误信息,将错误信息放入span标签,在页面显示,否则不显示#} --> 37 {% if error.UserName.0 %} 38 <span>{{ error.UserNamer.0 }}</span> 39 {% endif %} 40 </div> 41 <div class="input-group"> 42 密码:{{ form.Password }} 43 {% if error.Password.0 %} 44 <span>{{ error.Password.0 }}</span> 45 {% endif %} 46 </div> 47 <div class="input-group"> 48 邮箱:{{ form.Email }} 49 {% if error.Email.0 %} 50 <span>{{ error.Email.0 }}</span> 51 {% endif %} 52 </div> 53 <!-- <div class="input-group"> 54 详细介绍:{{ form.Memo }} 55 {% if error.Memo.0 %} 56 <span>{{ error.Memo.0 }}</span> 57 {% endif %}--> 58 </div> 59 <div class="input-group"> 60 书籍类型:{{ form.book_type }} 61 {% if error.book_type.0 %} 62 <span>{{ error.book_type.0 }}</span> 63 {% endif %} 64 </div> 65 66 <div> 67 <input type="submit" value="提交" /> 68 </div> 69 </form> 70 </body> 71 </html>
forms.py
1 #coding:UTF8 2 from django import forms 3 from app02 import models 4 5 class Form3(forms.Form): 6 UserName = forms.CharField( 7 widget=forms.TextInput(attrs={'class': 'c1'}), 8 error_messages={'required': '用户名不能为空'}, 9 ) 10 Password = forms.CharField(max_length=4, min_length=2,required=True) 11 Email = forms.EmailField(error_messages={'required': '邮箱不能为空', 'invalid': '邮箱格式错误'}) 12 13 #Memo = forms.CharField(required=False,widget=forms.Textarea()) 14 #直接写数据 15 user_type_choice = ( 16 (0, '普通用户'), 17 (1, '高级用户'), 18 ) 19 #通过BookType表查询信息,values_list拿到的是元组。id作为value显示,caption作为text在页面显示 20 # user_type_choice = models.BookType.objects.values_list('id', 'caption') 21 book_type = forms.CharField(widget=forms.widgets.Select(choices=user_type_choice, attrs={'class': "form-control"})) 22 23 24 #写上以下代码就不用担心数据库添加了数据而不能及时获取了 25 def __init__(self, *args, **kwargs): 26 #每次创建Form1对象时执行init方法 27 super(Form3, self).__init__(*args, **kwargs) 28 29 self.fields['book_type'] = forms.CharField( 30 widget=forms.widgets.Select(choices=models.BookType.objects.values_list('id', 'caption'), 31 attrs={'class': "form-control"}))
每天记录一点,就能多学一点,充实一点