Form
Form的驗證思路html
前端:form表單前端
後臺:建立form類,當請求到來時,先匹配,匹配出正確和錯誤信息。python
Django的Form驗證實例:mysql
建立project,進行基礎配置文件配置git
STATIC_URL = '/static/' STATICFILES_DIRS = ( os.path.join(BASE_DIR,"static"), )
MIDDLEWARE = [ 'django.middleware.security.SecurityMiddleware', 'django.contrib.sessions.middleware.SessionMiddleware', 'django.middleware.common.CommonMiddleware', # 'django.middleware.csrf.CsrfViewMiddleware', 'django.contrib.auth.middleware.AuthenticationMiddleware', 'django.contrib.messages.middleware.MessageMiddleware', 'django.middleware.clickjacking.XFrameOptionsMiddleware', ]
import pymysql pymysql.install_as_MySQLdb()
from django.conf.urls import url from django.contrib import admin from app01.views import account urlpatterns = [ url(r'^admin/', admin.site.urls), url(r'^form1/', account.form1), # url(r'^test/', account.test), ]
views.account.py:正則表達式
from django.shortcuts import render,HttpResponse from app01.forms import Form1 def form1(request): if request.method=="POST": #這裏POST必定要大寫 #一般獲取請求信息 #request.POST.get("user",None) #request.POST.get("pwd",None) #獲取請求內容,作驗證 f = Form1(request.POST) #request.POST:將接收到的數據經過Form1驗證 if f.is_valid(): #驗證請求的內容和Form1裏面的是否驗證經過。經過是True,不然False。 print(f.cleaned_data) #cleaned_data類型是字典,裏面是提交成功後的信息 else: #錯誤信息包含是否爲空,或者符合正則表達式的規則 print(type(f.errors),f.errors) #errors類型是ErrorDict,裏面是ul,li標籤 return render(request,"account/form1.html",{"error":f.errors}) return render(request,"account/form1.html")
html:sql
<body> {#{{ error }}接收後臺返回的錯誤信息封裝在ul,li標籤裏面:#} {{ error }} <form action="/form1/" method="POST"> <div> <input type="text" name="user" /> </div> <div> <input type="text" name="pwd" /> </div> <div> <input type="submit" value="提交" /> </div> </form> </body>
forms.py:數據庫
from django import forms class Form1(forms.Form): user = forms.CharField() pwd = forms.CharField()
訪問頁面:django
沒有輸入內容後提交,經過模板語言展現了錯誤信息json
Django強大之form驗證時不用自定義錯誤信息就能夠返回錯誤信息到前端以標籤方式展示。
.is_valid():返回True或者False
.cleaned_data:經過驗證後的數據
errors:
.error.get("user",None)error封裝全部的錯誤信息,若是沒有獲取到,默認爲None。
如:
.error.get["pwd"]直接獲取到ul、li。
如:
Form之精華版本
forms.py
from django import forms class Form1(forms.Form): user = forms.CharField() pwd = forms.CharField()
HTML:
<form action="/form1/" method="POST"> <div class="input-group"> {#接收後臺傳過來的form對象,自動生成input標籤#} {{ form.user }} {#從後臺傳過來的error是字典,直接{{ error.user.0 }}呈現錯誤信息#} {#若是後臺返回了錯誤信息,將錯誤信息放入span標籤,在頁面顯示,不然不顯示#} {% if error.user.0 %} <span>{{ error.user.0 }}</span> {% endif %} </div> <div class="input-group"> {{ form.pwd }} {% if error.pwd.0 %} <span>{{ error.pwd.0 }}</span> {% endif %} </div> <div> <input type="submit" value="提交" /> </div> </form>
account.py
def form1(request): if request.method == "POST": f = Form1(request.POST) if f.is_valid(): print(f.cleaned_data) else: return render(request,"account/form1.html",{"error":f.errors,"form":f}) else: # 若是不是post提交數據,就不傳參數建立對象,並將對象返回給前臺,直接生成input標籤,內容爲空 f = Form1() return render(request,"account/form1.html",{"form":f}) return render(request,"account/form1.html")
注:
頁面展現:
注:這裏的input標籤是後端返回form對象到前端經過{{ form.xxx }}所建立的
更強大的功能:
forms裏面的字段:
required:是否能夠爲空。required=True 不能夠爲空,required=False 能夠爲空 max_length=4 最多4個值,超過不會顯示 min_length=2 至少兩個值,少於兩個會返回提示信息 error_messages={'required': '郵箱不能爲空', 'invalid': '郵箱格式錯誤'} 自定義錯誤信息,invalid 是格式錯誤 widget=forms.TextInput(attrs={'class': 'c1'}) 給自動生成的input標籤自定義class屬性 widget=forms.Textarea() 生成Textarea標籤。widget默認生成input標籤
實戰:
models.py
from django.db import models # Create your models here. class Author(models.Model): """ 做者 """ name = models.CharField(max_length=100) age = models.IntegerField() class BookType(models.Model): """ 圖書類型 """ caption = models.CharField(max_length=64) class Book(models.Model): """ 圖書 """ name = models.CharField(max_length=64) pages = models.IntegerField() price = models.DecimalField(max_digits=10,decimal_places=2) pubdate = models.DateField() authors = models.ManyToManyField(Author) book_type = models.ForeignKey(BookType)
forms.py:
from django import forms from app01 import models class Form1(forms.Form): user = forms.CharField( widget=forms.TextInput(attrs={'class': 'c1'}), error_messages={'required': '用戶名不能爲空'}, ) pwd = forms.CharField(max_length=4, min_length=2,required=True) email = forms.EmailField(error_messages={'required': '郵箱不能爲空', 'invalid': '郵箱格式錯誤'}) memo = forms.CharField( widget=forms.Textarea() ) #直接寫數據 # user_type_choice = ( # (0, '普通用戶'), # (1, '高級用戶'), # ) #經過BookType表查詢信息,values_list拿到的是元組。id做爲value顯示,caption做爲text在頁面顯示 # user_type_choice = models.BookType.objects.values_list('id', 'caption') # book_type = forms.CharField( # widget=forms.widgets.Select(choices=user_type_choice, attrs={'class': "form-control"})) #寫上如下代碼就不用擔憂數據庫添加了數據而不能及時獲取了 def __init__(self, *args, **kwargs): #每次建立Form1對象時執行init方法 super(Form1, self).__init__(*args, **kwargs) self.fields['book_type'] = forms.CharField( widget=forms.widgets.Select(choices=models.BookType.objects.values_list('id', 'caption'), attrs={'class': "form-control"}))
HTML:
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> <style> .input-group{ position: relative; padding: 20px; width: 250px; } .input-group input{ width: 200px; display: inline-block; } .inline-group span{ display: inline-block; position: absolute; height: 12px; font-size: 8px; border: 1px solid red; background-color: coral; color: white; top: 41px; left: 20px; width: 202px; } </style> </head> <body> <form action="/form1/" method="POST"> <div class="input-group"> {# 接收後臺傳過來的form對象,自動生成input標籤#} {{ form.user }} {# 從後臺傳過來的error是字典,直接{{ error.user.0 }}呈現錯誤信息#} {# 若是後臺返回了錯誤信息,將錯誤信息放入span標籤,在頁面顯示,不然不顯示#} {% if error.user.0 %} <span>{{ error.user.0 }}</span> {% endif %} </div> <div class="input-group"> {{ form.pwd }} {% if error.pwd.0 %} <span>{{ error.pwd.0 }}</span> {% endif %} </div> <div class="input-group"> {{ form.email }} {% if error.email.0 %} <span>{{ error.email.0 }}</span> {% endif %} </div> <div class="input-group"> {{ form.memo }} {% if error.memo.0 %} <span>{{ error.memo.0 }}</span> {% endif %} </div> <div class="input-group"> {{ form.book_type }} {% if error.book_type.0 %} <span>{{ error.book_type.0 }}</span> {% endif %} </div> <div> <input type="submit" value="提交" /> </div> </form> </body> </html>
account.py:
from django.shortcuts import render,HttpResponse from app01.forms import Form1 from app01.models import * # def test(req): # BookType.objects.create(caption='技術') # BookType.objects.create(caption='文學') # BookType.objects.create(caption='動漫') # BookType.objects.create(caption='男人裝') # return HttpResponse("ok") def form1(request): if request.method == "POST": f = Form1(request.POST) if f.is_valid(): print(f.cleaned_data) else: return render(request,"account/form1.html",{"error":f.errors,"form":f}) else: # 若是不是post提交數據,就不傳參數建立對象,並將對象返回給前臺,直接生成input標籤,內容爲空 f = Form1() return render(request,"account/form1.html",{"form":f}) return render(request,"account/form1.html")
Django裏面沒有手機驗證,沒有的須要自定義
示例:
#!/usr/bin/env python # -*- coding:utf-8 -*- import re from django import forms from django.core.exceptions import ValidationError def mobile_validate(value): mobile_re = re.compile(r'^(13[0-9]|15[012356789]|17[678]|18[0-9]|14[57])[0-9]{8}$') if not mobile_re.match(value): raise ValidationError('手機號碼格式錯誤') class PublishForm(forms.Form): user_type_choice = ( (0, u'普通用戶'), (1, u'高級用戶'), ) user_type = forms.IntegerField(widget=forms.widgets.Select(choices=user_type_choice, attrs={'class': "form-control"})) title = forms.CharField(max_length=20, min_length=5, error_messages={'required': u'標題不能爲空', 'min_length': u'標題最少爲5個字符', 'max_length': u'標題最多爲20個字符'}, widget=forms.TextInput(attrs={'class': "form-control", 'placeholder': u'標題5-20個字符'})) memo = forms.CharField(required=False, max_length=256, widget=forms.widgets.Textarea(attrs={'class': "form-control no-radius", 'placeholder': u'詳細描述', 'rows': 3})) phone = forms.CharField(validators=[mobile_validate, ], error_messages={'required': u'手機不能爲空'}, widget=forms.TextInput(attrs={'class': "form-control", 'placeholder': u'手機號碼'})) email = forms.EmailField(required=False, error_messages={'required': u'郵箱不能爲空','invalid': u'郵箱格式錯誤'}, widget=forms.TextInput(attrs={'class': "form-control", 'placeholder': u'郵箱'}))
def publish(request): ret = {'status': False, 'data': '', 'error': '', 'summary': ''} if request.method == 'POST': request_form = PublishForm(request.POST) if request_form.is_valid(): request_dict = request_form.clean() print request_dict ret['status'] = True else: error_msg = request_form.errors.as_json() ret['error'] = json.loads(error_msg) return HttpResponse(json.dumps(ret))