Form介紹
咱們以前在HTML頁面中利用form表單向後端提交數據時,都會寫一些獲取用戶輸入的標籤而且用form標籤把它們包起來。html
與此同時咱們在好多場景下都須要對用戶的輸入作校驗,好比校驗用戶是否輸入,輸入的長度和格式等正不正確。若是用戶輸入的內容有錯誤就須要在頁面上相應的位置顯示對應的錯誤信息.。前端
Django form組件就實現了上面所述的功能。數據庫
總結一下,其實form組件的主要功能以下:django
- 生成頁面可用的HTML標籤
- 對用戶提交的數據進行校驗
- 保留上次輸入內容
- cleaned_data 是通過form表單清理過,通過驗證的數據。能夠直接使用。
普通的登陸
views.py
def login(request): error_msg = "" if request.method == "POST": username = request.POST.get("username") pwd = request.POST.get("pwd") if username == "Q1mi" and pwd == "123456": return HttpResponse("OK") else: error_msg = "用戶名或密碼錯誤" return render(request, "login.html", {"error_msg": error_msg})
login.html
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta http-equiv="x-ua-compatible" content="IE=edge"> <meta name="viewport" content="width=device-width, initial-scale=1"> <title>login</title> <style> .error { color: red; } </style> </head> <body> <form action="/login/" method="post"> {% csrf_token %} <p> <label for="username">用戶名</label> <input type="text" name="username" id="username"> </p> <p> <label for="pwd">密碼</label> <input type="password" name="pwd" id="pwd"> <span class="error"></span> </p> <p> <input type="submit"> <span class="error">{{ error_msg }}</span> </p> </form> </body> </html>
使用form組件
views.py
先定義好一個LoginForm類。後端
label 是這個字段在頁面顯示的名字post
class LoginForm(forms.Form): username = forms.CharField(min_length=8, label="用戶名") pwd = forms.CharField(min_length=6, label="密碼") def login2(request): error_msg = "" form_obj = LoginForm() if request.method == "POST": form_obj = LoginForm(request.POST) if form_obj.is_valid(): #對比你上面定義的類是否是符合條件,符合條件is_valis()就是True username = form_obj.cleaned_data.get("username") #經過這個方法來取值 pwd = form_obj.cleaned_data.get("pwd") if username == "Q1mi" and pwd == "123456": return HttpResponse("OK") else: error_msg = "用戶名或密碼錯誤" return render(request, "login2.html", {"form_obj": form_obj, "error_msg": error_msg})
login2.html
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta http-equiv="x-ua-compatible" content="IE=edge"> <meta name="viewport" content="width=device-width, initial-scale=1"> <title>login</title> <style> .error { color: red; } </style> </head> <body> <form action="/login2/" method="post" novalidate> {% csrf_token %} <p> {{ form_obj.username.label }} #這個能夠轉化成一個label標籤 {{ form_obj.username }} <span class="error">{{ form_obj.username.errors.0 }}</span> #這個是把字體給取出來了,不使用他的格式 </p> <p> {{ form_obj.pwd.label }} {{ form_obj.pwd }} <span class="error">{{ form_obj.pwd.errors.0 }}</span> </p> <p> <input type="submit"> <span class="error">{{ error_msg }}</span> </p> </form> </body> </html>
看網頁效果發現 也驗證了form的功能:
• 前端頁面是form類的對象生成的 -->生成HTML標籤功能
• 當用戶名和密碼輸入爲空或輸錯以後 頁面都會提示 -->用戶提交校驗功能
• 當用戶輸錯以後 再次輸入 上次的內容還保留在input框 -->保留上次輸入內容字體
Form那些事兒
經常使用字段與插件
建立Form類時,主要涉及到 【字段】 和 【插件】,字段用於對用戶請求數據的驗證,插件用於自動生成HTML;ui
initial
初始值,input框裏面的初始值。url
class LoginForm(forms.Form): username = forms.CharField( min_length=8, #用戶名的長短 label="用戶名", #label 標籤顯示的字體 initial="張三" # 設置默認值 ) pwd = forms.CharField(min_length=6, label="密碼")
error_messages
重寫錯誤信息。spa
class LoginForm(forms.Form): username = forms.CharField( min_length=8, label="用戶名", initial="張三", error_messages={ "required": "不能爲空", "invalid": "格式錯誤", "min_length": "用戶名最短8位" } ) pwd = forms.CharField(min_length=6, label="密碼")
password
class LoginForm(forms.Form): ... pwd = forms.CharField( min_length=6, label="密碼", widget=forms.widgets.PasswordInput(attrs={'class': 'c1'}, render_value=True ) ) #這個是input 是password 模式的。 在網頁上面用戶名或者密碼錯誤,不清楚密碼, True
radioSelect
單radio值爲字符串
class LoginForm(forms.Form): username = forms.CharField( min_length=8, label="用戶名", initial="張三", error_messages={ "required": "不能爲空", "invalid": "格式錯誤", "min_length": "用戶名最短8位" } ) pwd = forms.MultipleChoiceField (min_length=6, label="密碼") gender = forms.fields.ChoiceField( choices=((1, "男"), (2, "女"), (3, "保密")), label="性別", initial=3, widget=forms.widgets.RadioSelect # 是兩種選擇模式。 )
<p> {{ form_obj.gender.label }} {{ form_obj.gender }} <span class="error">{{ form_obj.errors.0 }}</span> </p>
單選Select
class LoginForm(forms.Form): ... hobby = forms.fields.ChoiceField( choices=((1, "籃球"), (2, "足球"), (3, "雙色球"), ), label="愛好", initial=3, widget=forms.widgets.Select )
多選Select
class LoginForm(forms.Form): ... hobby = forms.fields.MultipleChoiceField( choices=((1, "籃球"), (2, "足球"), (3, "雙色球"), ), label="愛好", initial=[1, 3], widget=forms.widgets.SelectMultiple )
單選checkbox
class LoginForm(forms.Form): ... keep = forms.fields.ChoiceField( label="是否記住密碼", initial="checked", widget=forms.widgets.CheckboxInput )
多選checkbox
class LoginForm(forms.Form): ... hobby = forms.fields.MultipleChoiceField( choices=((1, "籃球"), (2, "足球"), (3, "雙色球"),), label="愛好", initial=[1, 3], widget=forms.widgets.CheckboxSelectMultiple )
關於choice的注意事項:
在使用選擇標籤時,須要注意choices的選項能夠從數據庫中獲取,可是因爲是靜態字段 ***獲取的值沒法實時更新***,那麼須要自定義構造方法從而達到此目的。
方式一:
from django.forms import Form from django.forms import widgets from django.forms import fields class MyForm(Form): user = fields.ChoiceField( # choices=((1, '上海'), (2, '北京'),), initial=2, widget=widgets.Select ) def __init__(self, *args, **kwargs): super(MyForm,self).__init__(*args, **kwargs) # self.fields['user'].widget.choices = ((1, '上海'), (2, '北京'),) # 或 self.fields['user'].widget.choices = models.Classes.objects.all().values_list('id','caption')
方式二:
from django import forms from django.forms import fields from django.forms import models as form_model class FInfo(forms.Form): authors = form_model.ModelMultipleChoiceField(queryset=models.NNewType.objects.all()) # authors = form_model.ModelChoiceField(queryset=models.NNewType.objects.all())
Django form內置字段
校驗
方式一:
from django.forms import Form from django.forms import widgets from django.forms import fields from django.core.validators import RegexValidator class MyForm(Form): user = fields.CharField( validators=[RegexValidator(r'^[0-9]+$', '請輸入數字'), RegexValidator(r'^159[0-9]+$', '數字必須以159開頭')], )
方式二:
import re from django.forms import Form from django.forms import widgets from django.forms import fields 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(Form): title = fields.CharField(max_length=20, min_length=5, error_messages={'required': '標題不能爲空', 'min_length': '標題最少爲5個字符', 'max_length': '標題最多爲20個字符'}, widget=widgets.TextInput(attrs={'class': "form-control", 'placeholder': '標題5-20個字符'})) # 使用自定義驗證規則 phone = fields.CharField(validators=[mobile_validate, ], error_messages={'required': '手機不能爲空'}, widget=widgets.TextInput(attrs={'class': "form-control", 'placeholder': u'手機號碼'})) email = fields.EmailField(required=False, error_messages={'required': u'郵箱不能爲空','invalid': u'郵箱格式錯誤'}, widget=widgets.TextInput(attrs={'class': "form-control", 'placeholder': u'郵箱'}))
補充進階
應用Bootstrap樣式
Django form應用Bootstrap樣式簡單示例
批量添加樣式
可經過重寫form類的init方法來實現。
批量添加樣式