form 組件

  • 初始form組件

 

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

 

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

 

  1. 驗證功能
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
    <form method="post" action="/form/">
        <P><input type="text" name="username">{{ obj.errors.username.0 }}</P>
        <P><input type="password" name="pwd">{{ obj.errors.pwd.0 }}</P>
        <P><input type="text" name="age">{{ obj.errors.age.0 }}</P>
        <P><input type="text" name="email">{{ obj.errors.email.0 }}</P>
        <p><input type="submit"></p>
    </form>

</body>
</html>
from django import forms
from django.forms import fields


class RegisterForm(forms.Form):
    username = forms.CharField(max_length=20, min_length=6, required=True,
                               error_messages={
                                   'required':'用戶名不能爲空',
                                   'max_length': '最大長度20',
                                    'min_length': '最小長度6',
                               })
    pwd = forms.CharField(max_length=20, min_length=6, required=True)
    age = forms.IntegerField(required=True)
    email = forms.EmailField(required=True,error_messages={
        'invalid':'格式錯誤'
    })
from django.shortcuts import render
from myform.cfrom import RegisterForm
# Create your views here.


def form(request):
    if request.method == 'GET':
        return render(request, 'forms/index.html')
    else:
        print(request.POST)
        obj = RegisterForm(request.POST)
        if obj.is_valid():
            print(obj.cleaned_data)
        else:
            print(obj.errors)
    return render(request, 'forms/index.html',{'obj':obj})
  1. 生成input標籤功能
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
    <form method="post" action="/form/" novalidate>
        <P>{{ form_obj.username }}{{ form_obj.errors.username.0 }}</P>
        <P>{{ form_obj.pwd }}{{ form_obj.errors.pwd.0 }}</P>
        <P>{{ form_obj.age }}{{ form_obj.errors.age.0 }}</P>
        <P>{{ form_obj.email }}{{ form_obj.errors.email.0 }}</P>
        <p><input type="submit"></p>
    </form>

</body>
</html>
from django.shortcuts import render
from myform.cfrom import RegisterForm
# Create your views here.


def form(request):
    if request.method == 'GET':
        form_obj = RegisterForm()
        return render(request, 'forms/index.html', {'form_obj': form_obj})
    else:
        print(request.POST)
        form_obj = RegisterForm(request.POST)
        # obj = RegisterForm(request.POST)
        if form_obj.is_valid():
            print(form_obj.cleaned_data)
        else:
            print(form_obj.errors)
    return render(request, 'forms/index.html', { 'form_obj': form_obj})

 form類python

from django import forms
from django.forms import fields
from django.forms import widgets


class RegisterForm(forms.Form):
    username = fields.CharField(
        max_length=20,
        min_length=6,
        required=True,
        widget=widgets.TextInput(attrs={'v': 'v1', 'class': 'c1'}),
        initial='用戶名',
        label='用戶名',
        help_text='字母、數字、下劃線',
        disabled=False,
        label_suffix=':',
        error_messages={
            'required': '用戶名不能爲空',
            'max_length': '最大長度20',
            'min_length': '最小長度6',
        },
    )
    pwd = fields.CharField(
        max_length=20,
        min_length=6,
        required=True,
        label='密碼',
        widget=widgets.PasswordInput
    )
    age = fields.IntegerField(
        required=True,
        max_value=200,
        min_value=0,
        label='年齡',
    )
    email = fields.EmailField(required=True, error_messages={
        'invalid': '格式錯誤'
    },
                              label='郵箱',
                              )
    # 單選select
    city = fields.ChoiceField(
        choices=[
            (1, '中國'),
            (2, '美國'),
            (3, '日本'),
        ],
        initial=1,
        label='國籍',
    )
    # 多選select
    hobby = fields.MultipleChoiceField(
        choices=[
            (1, '音樂'),
            (2, '把妹'),
            (3, '約妹'),
        ],
        initial=[1, 3]
    )

    def __init__(self, *args, **kwargs):
        super(RegisterForm, self).__init__(*args, **kwargs)  # 必須在self.fieLds上面
        self.fields['hobby'].widget.choices = ((1, ''), (2, '嗨嗨'),)
        #
        # self.fields['hobby'].widget.choices = models.Classes.objects.all().value_list('id', 'caption')

    # 文件
    img = fields.FileField(
        label='圖片'
    )

    # 單選的checkbox
    chk = fields.CharField(
        widget=widgets.CheckboxInput(
            attrs={'v': 'v1', 'class': 'c1'}
        ),
        label='居住地'
    )

    # 多選checkbox,值爲列表
    dchk = fields.MultipleChoiceField(
        initial=[2, 1],
        choices=((1, '上海'),
                 (2, '北京'),),
        widget=widgets.CheckboxSelectMultiple,
        label='曾住地'
    )

    # 單選的radio
    rad = fields.CharField(
        widget=widgets.RadioSelect(choices=((1, ''), (2, ''),)),
        label='性別'
    )

    # 單radio,值爲字符串
    rad1 = fields.ChoiceField(
        choices=((1, ''), (2, ''),),
        initial=2,
        widget=widgets.RadioSelect(
            attrs={'class': 'll'}
        ),
        label='媳婦'
    )

 

注意:django

如果要生成 下拉菜單, 儘可能不要使用 fields.ChoiceField, 實際在提交的時候老是驗證錯誤。建議使用如下方式生成:app

from django import forms
from django.forms import fields
from django.forms import widgets
from app01 import models


def get_column_list():
    choices = models.ArticleColumn.objects.all().values_list('id', 'column')
    return choices


class ArticlePostForm(forms.Form):
    choice = get_column_list()

    def __init__(self, *args, **kwargs):
        super(ArticlePostForm, self).__init__(*args, **kwargs)  # 必須在self.fieLds上面
        self.fields['column'].widget.choices = get_column_list()

    title = fields.CharField(
        required=True,
        error_messages={
            'required': '標題爲空...'
        }
    )

    column = forms.CharField(
        required=True,
        widget=widgets.Select
          )

    body = fields.CharField(
        required=True,
        widget=widgets.Textarea,
        error_messages={
            'required': '內容爲空...'
        }
    )

 

驗證流程圖:函數

 

 

流程詳解

  1. 函數full_clean()依次調用每一個field的clean()函數,該函數針對field的max_length,unique等約束進行驗證,若是驗證成功則返回值,不然拋出ValidationError錯誤。若是有值返回,則放入form的cleaned_data字典中。
  2. 若是每一個field的內置clean()函數沒有拋出ValidationError錯誤,則調用以clean_開頭,以field名字結尾的自定義field驗證函數。驗證成功和失敗的處理方式同步驟1。
  3. 最後,調用form的clean()函數——注意,這裏是form的clean(),而不是field的clean()——若是clean沒有錯誤,那麼它將返回cleaned_data字典。
  4. 若是到這一步沒有ValidationError拋出,那麼cleaned_data字典就填滿了有效數據。不然cleaned_data不存在,form的另一個字典errors填上驗證錯誤。在template中,每一個field獲取本身錯誤的方式是:{{ form.username.errors }}。
  5. 最後,若是有錯誤is_valid()返回False,不然返回True。

注意一點:自定義驗證機制時:clean()和clean_<field>&()的最後必須返回驗證完畢或修改後的值.post

 

也就是說,自定義clean_fields 時,返回的是驗證過的字段數據。自定義clean() 是在最後一步,要返回完整的clean_data.ui

 

# 自定義驗證  驗證password
    def clean_password(self):
        user_data = cleaned_data.get('password')
        if user_data == 'XXX':
            raise forms.ValidationError(u'密碼太簡單了')
        return user_data

  

# 驗證選擇婚姻是否正確
    def clean_marry(self):
        data_list = self.cleaned_data['marry']
        if len(data_list) == 2:
            if '0' and '1' in data_list:
                raise forms.ValidationError('男女選擇有誤!')
            elif '2' and '3' in data_list:
                raise forms.ValidationError('婚姻選擇有誤!')
            else:
                return data_list
        else:
            raise forms.ValidationError('請選擇男女和婚姻!')
    def clean(self):
        cleaned_data = self.cleaned_data
        pwd = cleaned_data['pwd']

        pwd2 = cleaned_data['pwd2']
        print(pwd,pwd2)
        if pwd != pwd2:
            raise forms.ValidationError('二次輸入密碼不匹配')
        return cleaned_data #注意此處必定要return clean_data,不然會報錯
        
        

 自定義驗證規則spa

方式一:code

rom 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開頭')],
    )

方式二:orm

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'手機號碼'}))

參考文檔:http://www.cnblogs.com/wupeiqi/articles/6144178.html

 

class RegistrationForm(forms.Form):

    username = fields.CharField(
        required=True,
        error_messages={
            'required': '輸入用戶名...'
        }
    )
    email = fields.EmailField(
        required=True,
        error_messages={
            'required': '輸入郵箱...',
            'invalid':'格式錯誤...'
        }
    )

    password = fields.CharField(
        required=True,
        min_length=6,
        label='密碼',
        widget=widgets.PasswordInput,
        error_messages={
            'required': '輸入密碼...',
            'min_length': '最小長度爲6...'
        }
    )
    password_again = fields.CharField(
        required=True,
        widget=widgets.PasswordInput,
        label='確認密碼',
        error_messages = {
            'required': '輸入密碼...',
        }
    )

    def clean_username(self):
        username = self.cleaned_data['username']
        ret = UserInfo.objects.filter(username=username)
        if ret.exists():
            raise forms.ValidationError('用戶名已存在...')
        return username

    def clean(self):
        clean_data = self.cleaned_data
        if not self.errors:
            password1 = clean_data['password']
            password2 = clean_data['password_again']
            if password1 != password2:
                raise forms.ValidationError('兩次密碼不一致...')
        return clean_data
相關文章
相關標籤/搜索