有時時候咱們須要使用get,post,put等方式在前臺HTML頁面提交一些數據到後臺處理例 ;html
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Form</title> </head> <body> <div> <form action="url" method="post" enctype="multipart/form-data">{% csrf_token %} <input type="text" name="username"/> <input type="password" name="password"/> <input type="submit" value="submit"/> </form> </div> </body>
前端提交後臺獲取:前端
from django.shortcuts import render,HttpResponse,redirect
from app01 import models
def Login(request):
if request.method == "POST":
username = request.POST.get("username")
password = request.POST.get("password")
return HttpResponse("Hello,%s"%(username))
這樣就完成了基本的功能,基本上能夠用了。django
可是,若是用戶輸入並未按照要求(好比手機號要輸數據11位長度,密碼的複雜度等),還有就是提交後再回來已經輸入的數據也會沒了session
固然若是咱們手動將輸入以後的數據在 views 中都獲取到再傳遞到網頁,這樣是可行的,可是很不方便,因此 Django 提供了更簡單易用的 forms 來解決驗證等這一系列的問題app
,在這裏不得不提Django的插件庫真的很強大,簡單易擴展,上面的內容只是引進爲何要使用form,下面着重記錄django form的使用post
須要在django的APP中新建一個模塊form.py,具體內容以下 ui
class RegisterForm(forms.Form): email = forms.EmailField(required=True, error_messages={'required': "郵箱不能爲空"}) password = forms.CharField(max_length=120, min_length=6, required=True, error_messages={'required': "密碼不能爲空"}) invite_code = forms.CharField(required=True,error_messages={'required': "驗證碼不能爲空"})
前端頁面url
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>register</title> </head> <body> <div> <form action="url" method="post" enctype="multipart/form-data"> <input type="text" name="username"/> <input type="password" name="password"/> <input type="text" name="code"/> <input type="submit" value="submit"/> </form> </div> </body>
後臺views處理spa
def register(request): if request.method == "POST": f = Reg_Form(request.POST) if f.is_valid(): user = f.cleaned_data["username"] pwd = f.cleaned_data["password"] code = f.cleaned_data["code"] res_code = request.session.get("code", None) result = models.UserInfo.objects.filter(user__exact=user,pwd__exact=pwd) if code.upper() == res_code.upper() and result: models.UserInfo.objects.filter(user__exact=user).update(status=1) request.session["user"] = user return redirect("/home") else: 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),若是隻想看用戶的能夠
print(form.errors['username'][0])
錯誤信息咱們能夠經過 模板渲染回前端頁面,例
<form action="/form/" method="POST">
{% csrf_token %} <div class="input-group"> {#接收後臺傳過來的form對象,自動生成input標籤#} {{ form.user }} {#從後臺傳過來的error是字典,直接{{ error.user.0 }}呈現錯誤信息#} {#若是後臺返回了錯誤信息,將錯誤信息放入span標籤,在頁面顯示,不然不顯示#} {% if error.username.0 %} <span>{{ error.userusername.0 }}</span> {% endif %} </div> <div class="input-group"> {{ form.password }} {% if error.pwd.0 %} <span>{{ error.password .0 }}</span> {% endif %} </div> <div> <input type="submit" value="提交" /> </div> </form>
三.自生成input框插件
Form類
class RegisterForm(forms.Form): style = 'form-control input-lg' phone = forms.CharField(widget=forms.TextInput(attrs={'class': style, 'name': 'title'})), required=True, error_messages={'required': ugettext_lazy('*Required')}) code = forms.CharField(widget=forms.NumberInput(attrs={'placeholder': '驗證碼', 'class': style}), min_length=4, max_length=4, required=True, error_messages={'required': ugettext_lazy('*Required')}) password = forms.CharField(widget=forms.PasswordInput(attrs={'placeholder': '請輸入密碼', 'class': style}), min_length=6, required=True, error_messages={'required': ugettext_lazy('*Required')})
views
def register(request): if request.method == "POST": f = RegisterForm(request.POST) if f.is_valid(): user = f.cleaned_data["username"] pwd = f.cleaned_data["password"] code = f.cleaned_data["code"] res_code = request.session.get("CheckCode", None) result = models.UserInfo.objects.filter(user__exact=user,pwd__exact=pwd) if code.upper() == res_code.upper() and result: models.UserInfo.objects.filter(user__exact=user).update(status=1) request.session["user"] = user return redirect("/home") else: return render(request, "login.html", {"error": f.errors, "form": f}) else: return render(request, "login.html", {"error": f.errors, "form": f}) else: # 若是不是post提交數據,就不傳參數建立對象,並將對象返回給前臺,直接生成input標籤,內容爲空 f = Log_Form() return render(request, "login.html", {"form": f})
前端頁面
<body> <form action="/form/" method="POST">
{% csrf_token %}
<div class="input-group"> {# 接收後臺傳過來的form對象,自動生成input標籤#} {{ form.user }} {# 從後臺傳過來的error是字典,直接{{ error.user.0 }}呈現錯誤信息#} {# 若是後臺返回了錯誤信息,將錯誤信息放入span標籤,在頁面顯示,不然不顯示#} <div class="input-group"> {{ form.email }} {% if error.email.0 %} <span>{{ error.email.0 }}</span> {% endif %} </div> <div class="input-group"> {{ form.password }} {% if error.password.0 %} <span>{{ error.password.0 }}</span> {% endif %} </div> <div class="input-group"> {{ form.code }} {% if error.book_type.0 %} <span>{{ error.code.0 }}</span> {% endif %} </div> <div> <input type="submit" value="提交" /> </div> </form> </body> </html>
四.Form驗證完善
https://docs.djangoproject.com/en/dev/ref/forms/validation/
其中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屬性字典賦值。
from django import forms class RegisterForm(forms.Form): email = forms.EmailField(required=True, error_messages={'required': "郵箱不能爲空"}) password = forms.CharField(max_length=120, min_length=6, required=True, error_messages={'required': "密碼不能爲空"}) invite_code = forms.CharField(required=True,error_messages={'required': "驗證碼不能爲空"}) def clean(self): # 用戶名 try: email = self.cleaned_data['email'] except Exception as e: raise forms.ValidationError(u"註冊帳號需爲郵箱格式") # 驗證郵箱 user = User.objects.filter(username=email) if user: # 郵箱已經被註冊了 raise forms.ValidationError(u"郵箱已被註冊") # 密碼 try: password = self.cleaned_data['password'] except Exception as e: print('except: ' + str(e)) raise forms.ValidationError(u"請輸入至少6位密碼") return self.cleaned_data