Django之Form組件

新手上路

Django的Form主要具備一下幾大功能:javascript

  • 生成HTML標籤
  • 驗證用戶數據(顯示錯誤信息)
  • HTML Form提交保留上次提交數據
  • 初始化頁面顯示內容

經過Form驗證有倆種形式html

  • Form表單提交

    驗證、並能夠保留上次內容java

  • Ajax提交

    驗證、無需上次內容(Ajax提交數據頁面不會刷新)python

    返回HttpResponsegit

    前面根據回調函數值相應地作出跳轉或者顯示錯誤信息正則表達式

小試牛刀

一、建立Form類數據庫

二、View函數django

三、Html生成函數

初露鋒芒

建立Form類時,主要涉及到 【字段】 和 【插件】,字段用於對用戶請求數據的驗證,插件用於自動生成HTML;post

一、Django中Form類內置字段以下:

經常使用字段

詳細字段

二、Django內置插件

三、經常使用選擇插件

展露頭角

單選或者多選時、數據源是否能夠實時更新、、、

在使用選擇標籤時,須要注意choices的選項能夠從數據庫中獲取,可是因爲是靜態字段 ***獲取的值沒法實時更新***,那麼須要自定義構造方法從而達到此目的。

方式1、

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
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.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 ().value_list( 'id' , 'caption' )

方式2、

使用django提供的ModelChoiceField和ModelMultipleChoiceField字段來實現

?
1
2
3
4
5
6
7
8
9
10
from django import forms
from django.forms import fields
from django.forms import widgets
from django.forms import models as form_model
from django.core.exceptions import ValidationError
from django.core.validators import RegexValidator
  
class FInfo(forms.Form):
     authors = form_model.ModelMultipleChoiceField(queryset = models.NNewType.objects. all ())
     # authors = form_model.ModelChoiceField(queryset=models.NNewType.objects.all())

更上一層樓

經過上述,Django的Form組件提供驗證用戶提交的數據並能夠顯示錯誤信息(或自定製),更能能夠生成相應的Html代碼。更是猜測到,僅僅根據Form組件的驗證或許知足不了一些需求,因而創建再Form的驗證功能上使其有很強的擴展性

1、基於Form組件的字段上的簡單擴展

方式A

?
1
2
3
4
5
6
7
8
9
10
from django.forms import Form
from django.forms import widgets
from django.forms import fields
from django.core.validators import RegexValidator
 
 
class MyForm(Form):
     phone = fields.CharField(
         validators = [RegexValidator(r '^[0-9]+$' , '請輸入數字' ), RegexValidator(r '^188[0-9]+$' , '數字必須以188開頭' )],
     )

方式B

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
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 '郵箱' }))

2、基於源碼執行的流程上進行擴展

方式A

例如在註冊一個帳號時、經過Form的驗證其帳號符合規則時,還將要判斷該帳號是否存在於數據庫,如存在則確定是註冊不經過的

自定義方法、單一字段逐個再次驗證

複製代碼
from Formtest import models
from django import forms
from django.forms import fields
from django.forms import widgets
from django.core.exceptions import ValidationError,NON_FIELD_ERRORS
from django.core.validators import RegexValidator


class AjaxForm(forms.Form):
    user=fields.CharField(
        max_length=10,
        required=False,
        validators=[RegexValidator(r'^[a-z]+$', 'Enter a valid extension.', 'invalid')],
    )
    email=fields.EmailField()

    def clean_user(self):
        """
        Form中字段中定義的格式匹配完以後,執行此方法進行驗證
        :return:
        """
        v = self.cleaned_data['user']
        if models.UserInfo.objects.filter(user=v).count():
            raise ValidationError('此用戶名已經存在')
        return v

    def clean_email(self):
        """
        email驗證過以後、能夠自定義驗證該郵箱是否被使用...
        :return: 
        """
        pass
複製代碼

方式B

複製代碼
from Formtest import models
from django import forms
from django.forms import fields
from django.forms import widgets
from django.core.exceptions import ValidationError,NON_FIELD_ERRORS
from django.core.validators import RegexValidator


class AjaxForm(forms.Form):
    user = fields.CharField(
        max_length=10,
        required=False,
        validators=[RegexValidator(r'^[a-z]+$', 'Enter a valid extension.', 'invalid')],
    )
    email = fields.EmailField()

    def clean_user(self):
        """
        Form中字段中定義的格式匹配完以後,執行此方法進行驗證
        :return:
        """
        v = self.cleaned_data['user']
        if models.UserInfo.objects.filter(user=v).count():
            raise ValidationError('此用戶名已經存在')
        return v

    def clean_email(self):
        """
        email驗證過以後、能夠自定義驗證該郵箱是否被使用...
        :return:
        """
        pass

    def clean(self):
        """
        在單字段自定義驗證完成以後、也能夠對總體進行一個驗證
        :return: 
        """
        value_dict = self.cleaned_data
        user = value_dict.get('user')
        email = value_dict.get('email')
        if user == 'root' and email == 'root@163.com':
            raise ValidationError('身份驗證信息驗證失敗')
        return value_dict


    # ps: _post_clean是clean驗證完以後進一步驗證操做、通常用不到
    #       全局錯誤信息地鍵是 __all__
複製代碼
相關文章
相關標籤/搜索