Django之form表單

來源:互聯網
上載者:User

標籤:src   exti   初識   .sh   記住密碼   構造   false   tst   合格   

Form介紹

總結,form組件的主要功能如下:

  產生頁面可用的HTML標籤

  對使用者提交的資料進行校正

  保留上次輸入內容

  提示錯誤資訊

普通方式手寫註冊功能views.py
def register(request):    name_error = ‘‘    if request.method == ‘POST‘:        user = request.POST.get(‘user‘)        pwd = request.POST.get(‘pwd‘)        if len(user) < 6:            name_error = ‘使用者名稱太短了‘        else:            return HttpResponse(‘註冊成功‘)    return render(request, ‘register.html‘, {‘name_error‘: name_error})
register.html
<!DOCTYPE html><html lang="en"><head>    <meta charset="UTF-8">    <meta name="viewport" content="width=device-width, initial-scale=1">    <title>Title</title>    <link rel="stylesheet" href="/static/bootstrap-3.3.7/css/bootstrap.css">    <link rel="stylesheet" href="/static/font-awesome-4.7.0/css/font-awesome.css">    <link rel="stylesheet" href="/static/bootstrap-sweetalert-master/dist/sweetalert.css">    {% load static %}    <script src="{% static ‘bootstrap-sweetalert-master/dist/sweetalert.js‘ %}"></script>    <script src="{% static ‘jquery-3.3.1.min.js‘ %}"></script>    <script src="{% static ‘bootstrap-3.3.7/js/bootstrap.js‘ %}"></script></head><body><form action="" method="post">    {% csrf_token %}    <p>        使用者名稱:<input type="text" name="user"><span style="color: red">{{ name_error }}</span>    </p>    <p>        密碼:<input type="password" name="pwd">    </p>    <button type="submit">提交</button></form></body></html>
使用form組件實現註冊功能views.py

  先定義好一個RegForm類:

from django import forms# 按照Django form組件的要求自己寫一個類class RegForm(forms.Form):    user = forms.CharField(label=‘使用者名稱‘)    pwd = forms.CharField(label=‘密碼‘)

  再寫一個視圖函數:

# 使用form組件實現註冊方式def register2(request):    form_obj = RegForm()    if request.method == ‘POST‘:        # 執行個體化form對象的時候,把post提交過來的資料直接傳進去        form_obj = RegForm(request.POST)        # 調用form_obj校正資料的方法        if form_obj.is_valid():            return HttpResponse(‘註冊成功‘)    return render(request, ‘register2.html‘, {‘form_obj‘: form_obj})

  進階版視圖函數:

from django import formsfrom django.forms import widgetsfrom app01 import modelsfrom django.core.validators import RegexValidatorfrom django.core.exceptions import ValidationErrorimport redef check_name(value):    if ‘alex‘ in value:        raise ValidationError(‘不符合社會主義核心價值觀‘)# 定義formclass RegForm(forms.Form):    user = forms.CharField(        label=‘使用者名稱‘,        required=False,  # 不允許為空白        min_length=6,  # 最小長度為6        initial=‘wjs521‘,  # 初識值為wjs521        disabled=False,  # 不可以編輯        validators=[check_name],        error_messages={            ‘min_length‘: ‘你的長度太短了,還不到6‘,            ‘required‘: ‘不可為空‘        }    )    #    pwd = forms.CharField(        label=‘密碼‘,        min_length=6,        widget=widgets.PasswordInput()  # HTML外掛程式,頁面顯示密碼時是密文的    )    re_pwd = forms.CharField(        label=‘確認密碼‘,        min_length=6,        widget=widgets.PasswordInput()    )    #    # gender = forms.ChoiceField(    #     choices=((1, ‘男‘), (2, ‘女‘), (3, ‘不詳‘)),    #     widget=widgets.CheckboxSelectMultiple()  # 可以進行多選的多選框    # )    #    # hobby = forms.ChoiceField(    #     # choices=((1, ‘足球‘), (2, ‘籃球‘), (3, ‘雙色球‘)),    #     choices=models.Hobby.objects.all().values_list(‘id‘, ‘name‘),    #     widget=widgets.SelectMultiple()  # 可以多個選擇    # )    phone = forms.CharField(        label=‘手機號‘,        # validators=[        #     RegexValidator(r‘^1[3-9]\d{9}$‘, ‘手機號不正經‘)        # ]    )    # def __init__(self, *args, **kwargs):    #     super().__init__(*args, **kwargs)    #     self.fields[‘hobby‘].choices = models.Hobby.objects.all().values_list(‘id‘, ‘name‘)    # def clean_phone(self):    #     value = self.cleaned_data.get(‘phone‘)    #     if re.match(r‘^1[3-9]\d{9}$‘,value):    #         return value    #    #     raise ValidationError(‘手機號不正經‘)    # def clean_re_pwd(self):    #     pwd = self.cleaned_data.get(‘pwd‘)    #     re_pwd = self.cleaned_data.get(‘re_pwd‘)    #    #     if pwd == re_pwd:    #         return re_pwd    #     raise ValidationError(‘兩次密碼不一致‘)    def clean(self):        pwd = self.cleaned_data.get(‘pwd‘)        re_pwd = self.cleaned_data.get(‘re_pwd‘)        if pwd == re_pwd:            return self.cleaned_data        self.add_error(‘re_pwd‘,‘兩次密碼不一致‘)        raise ValidationError(‘兩次密碼不一致‘)
from django.shortcuts import render, HttpResponsefrom app01.forms import RegFormdef register(request):    name_error = ‘‘    if request.method == ‘POST‘:        user = request.POST.get(‘user‘)        pwd = request.POST.get(‘pwd‘)        if len(user) < 6:            name_error = ‘你太短了‘        else:            # 資料時合格的 進行資料的操作            return HttpResponse(‘註冊成功‘)    return render(request, ‘register.html‘, {"name_error": name_error})def register2(request):    form_obj = RegForm()    # print(RegForm.hobby.choices)    # print(11,form_obj.fields[‘hobby‘].choices)    if request.method == ‘POST‘:        form_obj = RegForm(request.POST)        if form_obj.is_valid():            # cleaned_data  是經過校正的資料            print(form_obj.cleaned_data)            # 資料操作            return HttpResponse(‘註冊成功‘)    return render(request, ‘register2.html‘, {"form_obj": form_obj})
register2.html
<!DOCTYPE html><html lang="en"><head>    <meta charset="UTF-8">    <meta name="viewport" content="width=device-width, initial-scale=1">    <title>註冊2</title>    <link rel="stylesheet" href="/static/bootstrap-3.3.7/css/bootstrap.css">    <link rel="stylesheet" href="/static/font-awesome-4.7.0/css/font-awesome.css">    <link rel="stylesheet" href="/static/bootstrap-sweetalert-master/dist/sweetalert.css">    {% load static %}    <script src="{% static ‘bootstrap-sweetalert-master/dist/sweetalert.js‘ %}"></script>    <script src="{% static ‘jquery-3.3.1.min.js‘ %}"></script>    <script src="{% static ‘bootstrap-3.3.7/js/bootstrap.js‘ %}"></script></head><body>{# novalidate 屬性是一個布爾屬性。 #}{# novalidate 屬性規定當提交表單時不對錶單資料(輸入)進行驗證。 #}{# input 的屬性autocomplete 預設為on #}{# 其含義代表是否讓瀏覽器自動記錄之前輸入的值 #}{# 很多時候,需要對客戶的資料進行保密,防止瀏覽器軟體或者惡意外掛程式擷取到 #}{# 可以在input中加入autocomplete="off" 來關閉記錄 #}{# 系統需要保密的情況下可以使用此參數 #}<form action="" method="post" novalidate autocomplete="off">    {% csrf_token %}    {#    {{ form_obj.as_p }} {# 這裡是自動產生多個p標籤#}    <p>        {{ form_obj.user.label }} {# 匯入給定的label屬性的值 #}        {{ form_obj.user }} {# 產生某個欄位的input框 #}        <span style="color: red;">{{ form_obj.user.errors.0 }}</span> {# 當做正常的常值內容來展現 #}        <span style="color: red;">{{ form_obj.user.errors }}</span> {# 不取0的話會當做一個標籤展現出來 #}    </p>    <p>        {{ form_obj.pwd.label }}        {{ form_obj.pwd }} {# 產生某個欄位的input框 #}        <span style="color: red">{{ form_obj.pwd.errors.0 }}</span>        <span style="color: red">{{ form_obj.pwd.errors }}</span>    </p>    <button>註冊</button></form></body></html>
常用欄位與外掛程式

建立Form類時,主要涉及到【欄位】和【外掛程式】,欄位用於對使用者請求資料的驗證,外掛程式用於自動產生HTML;

initial

初始值,input框裡面的初始值。

class LoginForm(forms.Form):    username = forms.CharField(        min_length=8,        label=‘使用者名稱‘,        initial=‘wjs‘  # 設定預設值    )    pwd = forms.CharField(min_length=6, label=‘密碼‘)
error_messages

重寫錯誤資訊。

from django import formsclass LoginForm(forms.Form):    username = forms.CharField(        min_length=8,        label=‘使用者名稱‘,        error_messages={            ‘required‘: ‘不可為空‘,            ‘invalid‘: ‘格式錯誤‘,            ‘min_length‘: ‘使用者名稱最短8位‘        }    )    pwd = forms.CharField(min_length=6, label=‘密碼‘)
password
from django import formsclass LoginForm(forms.Form):    pwd = forms.CharField(        min_length=6,        label=‘密碼‘,        widget=forms.widgets.PasswordInput(attrs={‘class‘:‘c1‘},        render_value=True        )    )
RadioSelect

單radio值為字串

from django import formsfrom django.forms import widgetsclass LoginForm(forms.Form):    gender = forms.fields.ChoiceField(        choices=((1, ‘男‘), (2, ‘女‘), (3, ‘不詳‘)),        label=‘性別‘,        initial=3,        widget=forms.widgets.RadioSelect()    )# 單選項
單選Select
from django.forms import widgetsclass 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 Formfrom django.forms import widgetsfrom django.forms import fieldsclass MyForm(Form):    user = fields.ChoiceField(        # choices=((1, ‘上海‘), (2, ‘北京‘)),        initial=2,        widget=widgets.Select    )        # 當後台手動的給資料庫添加資料時,前台不能的及時擷取到新添加的資料,需要重新啟動伺服器,比較麻煩。所以通過調用父類的__init__()方法——重新整理頁面時就會擷取到新的資料。    def __init__(self, *args, **kwargs):        super(MyForm,self).__init__(*args, **kwargs)        # self.fields[‘user‘].choices = ((1, ‘上海‘), (2, ‘北京‘)),        # 或        self.fields[‘user‘].choices = models.Classes.objects.all().values_list(‘id‘,‘caption‘)

方式二:

from django import formsfrom django.forms import fieldsfrom django.forms import models as form_modelclass FInfo(forms.Form):    # 多選    authors = form_model.ModelMutipleChoiceField(queryset=models.NNewType.objects.all())    # 單選    # authors = form_model.ModelChoiceField(queryset=models.NNewType.objects.all())
Django Form所有內建欄位
Field    required=True,               是否允許為空白    widget=None,                 HTML外掛程式    label=None,                  用於產生Label標籤或顯示內容    initial=None,                初始值    help_text=‘‘,                協助資訊(在標籤旁邊顯示)    error_messages=None,         錯誤資訊 {‘required‘: ‘不可為空‘, ‘invalid‘: ‘格式錯誤‘}    validators=[],               自訂驗證規則    localize=False,              是否支援本地化    disabled=False,              是否可以編輯    label_suffix=None            Label內容尾碼  CharField(Field)    max_length=None,             最大長度    min_length=None,             最小長度    strip=True                   是否移除使用者輸入空白 IntegerField(Field)    max_value=None,              最大值    min_value=None,              最小值 FloatField(IntegerField)    ... DecimalField(IntegerField)    max_value=None,              最大值    min_value=None,              最小值    max_digits=None,             總長度    decimal_places=None,         小數位長度 BaseTemporalField(Field)    input_formats=None          時間格式化    DateField(BaseTemporalField)    格式:2015-09-01TimeField(BaseTemporalField)    格式:11:12DateTimeField(BaseTemporalField)格式:2015-09-01 11:12 DurationField(Field)            時間間隔:%d %H:%M:%S.%f    ... RegexField(CharField)    regex,                      自定製Regex    max_length=None,            最大長度    min_length=None,            最小長度    error_message=None,         忽略,錯誤資訊使用 error_messages={‘invalid‘: ‘...‘} EmailField(CharField)          ... FileField(Field)    allow_empty_file=False     是否允許空檔案 ImageField(FileField)          ...    註:需要PIL模組,pip3 install Pillow    以上兩個字典使用時,需要注意兩點:        - form表單中 enctype="multipart/form-data"        - view函數中 obj = MyForm(request.POST, request.FILES) URLField(Field)    ...  BooleanField(Field)      ... NullBooleanField(BooleanField)    ... ChoiceField(Field)    ...    choices=(),                選項,如:choices = ((0,‘上海‘),(1,‘北京‘),)    required=True,             是否必填    widget=None,               外掛程式,預設select外掛程式    label=None,                Label內容    initial=None,              初始值    help_text=‘‘,              協助提示  ModelChoiceField(ChoiceField)    ...                        django.forms.models.ModelChoiceField    queryset,                  # 查詢資料庫中的資料    empty_label="---------",   # 預設空顯示內容    to_field_name=None,        # HTML中value的值對應的欄位    limit_choices_to=None      # ModelForm中對queryset二次篩選     ModelMultipleChoiceField(ModelChoiceField)    ...                        django.forms.models.ModelMultipleChoiceField       TypedChoiceField(ChoiceField)    coerce = lambda val: val   對選中的值進行一次轉換    empty_value= ‘‘            空值的預設值 MultipleChoiceField(ChoiceField)    ... TypedMultipleChoiceField(MultipleChoiceField)    coerce = lambda val: val   對選中的每一個值進行一次轉換    empty_value= ‘‘            空值的預設值 ComboField(Field)    fields=()                  使用多個驗證,如下:即驗證最大長度20,又驗證郵箱格式                               fields.ComboField(fields=[fields.CharField(max_length=20), fields.EmailField(),]) MultiValueField(Field)    PS: 抽象類別,子類中可以實現彙總多個字典去匹配一個值,要配合MultiWidget使用 SplitDateTimeField(MultiValueField)    input_date_formats=None,   格式列表:[‘%Y--%m--%d‘, ‘%m%d/%Y‘, ‘%m/%d/%y‘]    input_time_formats=None    格式列表:[‘%H:%M:%S‘, ‘%H:%M:%S.%f‘, ‘%H:%M‘] FilePathField(ChoiceField)     檔案選項,目錄下檔案顯示在頁面中    path,                      檔案夾路徑    match=None,                正則匹配    recursive=False,           遞迴下面的檔案夾    allow_files=True,          允許檔案    allow_folders=False,       允許檔案夾    required=True,    widget=None,    label=None,    initial=None,    help_text=‘‘ GenericIPAddressField    protocol=‘both‘,           both,ipv4,ipv6支援的IP格式    unpack_ipv4=False          解析ipv4地址,如果是::ffff:192.0.2.1時候,可解析為192.0.2.1, PS:protocol必須為both才能啟用 SlugField(CharField)           數字,字母,底線,減號(連字號)    ... UUIDField(CharField)           uuid類型Django Form內建欄位  
校正用內建驗證規則:
from django.forms import Formfrom django.forms import widgetsfrom django.forms import fieldsfrom django.core.validators import RegexValidator# RegexValidator正則校正 class MyForm(Form):    user = fields.CharField(        validators=[RegexValidator(r‘^[0-9]+$‘, ‘請輸入數字‘),             RegexValidator(r‘^159[0-9]+$‘, ‘數字必須以159開頭‘)],    )  
自訂驗證規則:
import refrom django.forms import Formfrom django.forms import widgetsfrom django.forms import fieldsfrom django.core.exceptions import ValidationError# 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‘郵箱‘}))
鉤子函數1. 局部鉤子
def clean_phone(self):value = self.cleaned_data.get(‘phone‘)if re.match(r‘^1[3-9]\d{9}$‘,value):return valueraise ValidationError(‘手機號不正經‘)
2. 全域的鉤子
def clean(self):pwd = self.cleaned_data.get(‘pwd‘)re_pwd = self.cleaned_data.get(‘re_pwd‘)if pwd == re_pwd:return self.cleaned_dataself.add_error(‘re_pwd‘,‘兩次密碼不一致‘)raise ValidationError(‘兩次密碼不一致‘)

 

Django之form表單

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.