【python】-- Django Form

 Django  Form

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

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

1、Form 簡單示例:

一、view中建立Form類並進行函數處理python

from django import forms  # 導入forms
class FM(forms.Form):
    user = forms.CharField()
    pwd = forms.CharField()
    email = forms.EmailField()

def fm(request):
    if request.method == "GET":
        obj = FM()
        return render(request, 'fm.html', {'obj': obj})
    elif request.method == "POST":
        # 獲取用戶全部數據
        # 每條數據請求的驗證
        # 成功:獲取全部的正確的信息
        # 失敗:顯示錯誤信息
        obj = FM(request.POST)  # 生成from表單驗證對象實例
        r1 = obj.is_valid()   # 獲取obj對象是否有效
        if r1:
            # obj.cleaned_data
            print(r1)
            print(obj.changed_data)

        else:
            print(r1)
            print(obj.errors.as_json())
            # 錯誤信息字典形式
            #  {"user": [{"message": "This field is required.", "code": "required"}],
            #  "pwd": [{"message": "This field is required.", "code": "required"}],
            #  "email": [{"message": "This field is required.", "code": "required"}]}
            print(obj.errors['user'][0])
        return redirect("/fm/")

二、生成HTMLjquery

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title></title>
</head>
<body>
    <form action="/fm/" method="POST">
        {% csrf_token %}
{#        <!--第一種 input框形式-->#}
{#        <p><input type="text" name="user"/>  {{ obj.errors.user.0 }}</p> <!--user pwd email 必需要跟視圖中的繼承forms.Form類中的相應實例名稱一致-->#}
{#        <p><input type="text" name="pwd"/>   {{ obj.errors.pwd.0 }}</p>#}
{#        <p><input type="text" name="email"/> {{ obj.errors.email.0 }}</p>#}
        <!--第二種 obj.user框形式-->
        <p>{{ obj.user }} {{ obj.errors.user.0 }}</p>  <!-- 相似於view視圖中的 obj.errors['user'][0]-->
        <p>{{ obj.pwd }} {{ obj.errors.pwd.0 }}</p>
        <p>{{ obj.email }}{{ obj.errors.email.0 }}</p>

{#        <!--第三種 obj.as_p、obj.as_ul、 obj.as_table(須要在外面添加table標籤)框形式,生成方便,自定義樣式不強-->#}
{#          {{ obj.as_p }}#}
{#          {{ obj.as_ul }}#}
{#            <table>#}
{#          {{ obj.as_table }}#}
{#            </table>#}
        <input type="submit" value="提交" />
    </form>
</body>
</html>

 

 

2、Form類

 建立Form類時,主要涉及到 fields【字段】 和 wiegets【插件】,功能特性:字段用於對用戶請求數據的驗證,插件用於自動生成HTML(保留上一次提交的數據)。使用場景:一、在新url方式操做時,字段和插件都須要用到,由於在from提交以後,頁面也會被刷新,而插件能夠保留上一次的提交數據。二、在用Ajax請求操做時,能夠只用到字段的驗證功能,由於Ajax請求頁面不會刷新,上一次提交數據仍然保留在頁面,固然在用Ajax請求操做時也可使用插件。git

一、Django內置字段以下:web

  1 Field
  2     required=True,               是否容許爲空
  3     widget=None,                 HTML插件
  4     label=None,                  用於生成Label標籤或顯示內容
  5     initial=None,                初始值
  6     help_text='',                幫助信息(在標籤旁邊顯示)
  7     error_messages=None,         錯誤信息 {'required': '不能爲空', 'invalid': '格式錯誤'}
  8     show_hidden_initial=False,   是否在當前插件後面再加一個隱藏的且具備默認值的插件(可用於檢驗兩次輸入是否一直)
  9     validators=[],               自定義驗證規則
 10     localize=False,              是否支持本地化
 11     disabled=False,              是否能夠編輯
 12     label_suffix=None            Label內容後綴
 13  
 14  
 15 CharField(Field)
 16     max_length=None,             最大長度
 17     min_length=None,             最小長度
 18     strip=True                   是否移除用戶輸入空白
 19  
 20 IntegerField(Field)
 21     max_value=None,              最大值
 22     min_value=None,              最小值
 23  
 24 FloatField(IntegerField)
 25     ...
 26  
 27 DecimalField(IntegerField)
 28     max_value=None,              最大值
 29     min_value=None,              最小值
 30     max_digits=None,             總長度
 31     decimal_places=None,         小數位長度
 32  
 33 BaseTemporalField(Field)
 34     input_formats=None          時間格式化   
 35  
 36 DateField(BaseTemporalField)    格式:2015-09-01
 37 TimeField(BaseTemporalField)    格式:11:12
 38 DateTimeField(BaseTemporalField)格式:2015-09-01 11:12
 39  
 40 DurationField(Field)            時間間隔:%d %H:%M:%S.%f
 41     ...
 42  
 43 RegexField(CharField)
 44     regex,                      自定製正則表達式
 45     max_length=None,            最大長度
 46     min_length=None,            最小長度
 47     error_message=None,         忽略,錯誤信息使用 error_messages={'invalid': '...'}
 48  
 49 EmailField(CharField)      
 50     ...
 51  
 52 FileField(Field)
 53     allow_empty_file=False     是否容許空文件
 54  
 55 ImageField(FileField)      
 56     ...
 57     注:須要PIL模塊,pip3 install Pillow
 58     以上兩個字典使用時,須要注意兩點:
 59         - form表單中 enctype="multipart/form-data"
 60         - view函數中 obj = MyForm(request.POST, request.FILES)
 61  
 62 URLField(Field)
 63     ...
 64  
 65  
 66 BooleanField(Field)  
 67     ...
 68  
 69 NullBooleanField(BooleanField)
 70     ...
 71  
 72 ChoiceField(Field)
 73     ...
 74     choices=(),                選項,如:choices = ((0,'上海'),(1,'北京'),)
 75     required=True,             是否必填
 76     widget=None,               插件,默認select插件
 77     label=None,                Label內容
 78     initial=None,              初始值
 79     help_text='',              幫助提示
 80  
 81  
 82 ModelChoiceField(ChoiceField)
 83     ...                        django.forms.models.ModelChoiceField
 84     queryset,                  # 查詢數據庫中的數據
 85     empty_label="---------",   # 默認空顯示內容
 86     to_field_name=None,        # HTML中value的值對應的字段
 87     limit_choices_to=None      # ModelForm中對queryset二次篩選
 88      
 89 ModelMultipleChoiceField(ModelChoiceField)
 90     ...                        django.forms.models.ModelMultipleChoiceField
 91  
 92  
 93      
 94 TypedChoiceField(ChoiceField)
 95     coerce = lambda val: val   對選中的值進行一次轉換
 96     empty_value= ''            空值的默認值
 97  
 98 MultipleChoiceField(ChoiceField)
 99     ...
100  
101 TypedMultipleChoiceField(MultipleChoiceField)
102     coerce = lambda val: val   對選中的每個值進行一次轉換
103     empty_value= ''            空值的默認值
104  
105 ComboField(Field)
106     fields=()                  使用多個驗證,以下:即驗證最大長度20,又驗證郵箱格式
107                                fields.ComboField(fields=[fields.CharField(max_length=20), fields.EmailField(),])
108  
109 MultiValueField(Field)
110     PS: 抽象類,子類中能夠實現聚合多個字典去匹配一個值,要配合MultiWidget使用
111  
112 SplitDateTimeField(MultiValueField)
113     input_date_formats=None,   格式列表:['%Y--%m--%d', '%m%d/%Y', '%m/%d/%y']
114     input_time_formats=None    格式列表:['%H:%M:%S', '%H:%M:%S.%f', '%H:%M']
115  
116 FilePathField(ChoiceField)     文件選項,目錄下文件顯示在頁面中
117     path,                      文件夾路徑
118     match=None,                正則匹配
119     recursive=False,           遞歸下面的文件夾
120     allow_files=True,          容許文件
121     allow_folders=False,       容許文件夾
122     required=True,
123     widget=None,
124     label=None,
125     initial=None,
126     help_text=''
127  
128 GenericIPAddressField
129     protocol='both',           both,ipv4,ipv6支持的IP格式
130     unpack_ipv4=False          解析ipv4地址,若是是::ffff:192.0.2.1時候,可解析爲192.0.2.1, PS:protocol必須爲both才能啓用
131  
132 SlugField(CharField)           數字,字母,下劃線,減號(連字符)
133     ...
134  
135 UUIDField(CharField)           uuid類型 UUID是根據MAC以及當前時間等建立的不重複的隨機字符串
136     ...
fields-字段

二、Django內置插件:ajax

 1 TextInput(Input)
 2 NumberInput(TextInput)
 3 EmailInput(TextInput)
 4 URLInput(TextInput)
 5 PasswordInput(TextInput)
 6 HiddenInput(TextInput)
 7 Textarea(Widget)
 8 DateInput(DateTimeBaseInput)
 9 DateTimeInput(DateTimeBaseInput)
10 TimeInput(DateTimeBaseInput)
11 CheckboxInput
12 Select
13 NullBooleanSelect
14 SelectMultiple
15 RadioSelect
16 CheckboxSelectMultiple
17 FileInput
18 ClearableFileInput
19 MultipleHiddenInput
20 SplitDateTimeWidget
21 SplitHiddenDateTimeWidget
22 SelectDateWidget
wiegets-插件

2.一、經常使用的內置插件演示:正則表達式

 1 # 單radio,值爲字符串
 2 # user = fields.CharField(
 3 #     initial=2,
 4 #     widget=widgets.RadioSelect(choices=((1,'上海'),(2,'北京'),))
 5 # )
 6  
 7 # 單radio,值爲字符串
 8 # user = fields.ChoiceField(
 9 #     choices=((1, '上海'), (2, '北京'),),
10 #     initial=2,
11 #     widget=widgets.RadioSelect
12 # )
13  
14 # 單select,值爲字符串
15 # user = fields.CharField(
16 #     initial=2,
17 #     widget=widgets.Select(choices=((1,'上海'),(2,'北京'),))
18 # )
19  
20 # 單select,值爲字符串
21 # user = fields.ChoiceField(
22 #     choices=((1, '上海'), (2, '北京'),),
23 #     initial=2,
24 #     widget=widgets.Select
25 # )
26  
27 # 多選select,值爲列表
28 # user = fields.MultipleChoiceField(
29 #     choices=((1,'上海'),(2,'北京'),),
30 #     initial=[1,],
31 #     widget=widgets.SelectMultiple
32 # )
33  
34  
35 # 單checkbox
36 # user = fields.CharField(
37 #     widget=widgets.CheckboxInput()
38 # )
39  
40  
41 # 多選checkbox,值爲列表
42 # user = fields.MultipleChoiceField(
43 #     initial=[2, ],
44 #     choices=((1, '上海'), (2, '北京'),),
45 #     widget=widgets.CheckboxSelectMultiple
46 # )
經常使用內置插件演示

2.二、Form操做動態Select數據:數據庫

 1 # forms.py  在app目錄下建立forms.py文件,來專門存放form驗證的代碼
 2 from django.forms import widgets,forms,fields
 3 from app01 import models
 4 
 5 class UserForm(forms.Form):
 6 
 7     name = fields.CharField(
 8         required=False,
 9         widget=widgets.TextInput(attrs={'class':'c1'})
10     )
11 
12     email = fields.EmailField(
13         max_length=12,
14         widget=widgets.TextInput(attrs={"class":"c2"})
15     )
16 
17     user_type = fields.ChoiceField
18         ### 第一種form動態獲取select數據
19         #靜態變量,僅在程序第一次加載時執行,從數據庫讀取數據保存至內存,重啓服務才能從數據庫獲取最新數據
20         # choices=models.UserType.objects.values_list('id','type_name'),
21 
22         ### 第二種form動態獲取select數據,自定義構造方法,
23         choices=[],
24         widget=widgets.Select
25     )
26 
27     user_type2 = fields.CharField(widget=widgets.Select(choices=[])) #fields['user_type2'].widget.choices
28 
29     def __init__(self,*args,**kwargs):
30         super(UserForm,self).__init__(*args,**kwargs)
31 
32         # 構造方法中實例變量會在每次實例化後執行
33         self.fields["user_type"].choices = models.UserType.objects.values_list('id','type_name')
34         self.fields['user_type2'].widget.choices = models.UserType.objects.values_list('id','type_name')
35 
36 
37 
38 # view.py  在view.py視圖函數中去調用From驗證
39 
40 from django.shortcuts import render
41 from app01 import models
42 
43 def index(request):
44     from app01.forms import UserForm
45     ### 第一種form動態獲取select數據
46     #obj = UserForm() # 實例化UserForm類
47     # obj.fields["user_type"].choices=models.UserType.objects.values_list('id','type_name') #每次刷新web頁面就至關於實例化一次UserForm類,從而從數據庫獲取最新數據
48 
49     ### 第二種form動態獲取select數據,自定義構造方法
50     obj = UserForm() #實例化UserForm類,這裏只須要實例化,而form UserForm類中重寫的構造方法中的實例變量會在每次實例化以後執行一次
51     return render(request,'index.html',{'obj':obj})
52 
53 
54 
55 #HTML
56 <body>
57     <p>{{ obj.name }}</p>
58     <p>{{ obj.email }}</p>
59     <p>{{ obj.user_type }}</p>
60     <p>{{ obj.user_type2 }}</p>
61 </body>
方式一,自定義構造方法
 1 ##form.py
 2 #ModelChoiceField具體字段以下:
 3 ModelChoiceField(ChoiceField)
 4     ...                        django.forms.models.ModelChoiceField
 5     queryset,                  # 查詢數據庫中的數據
 6     empty_label="---------",   # 默認空顯示內容
 7     to_field_name=None,        # HTML中value的值對應的字段
 8     limit_choices_to=None      # ModelForm中對queryset二次篩選 ###
 9 
10 
11 
12 from django.forms import widgets,forms,fields
13 from django.forms.models import ModelChoiceField  #django本身幫咱們提供的
14 
15 class UserForm(forms.Form):
16         user_type3 = ModelChoiceField(
17         queryset=models.UserType.objects.all(),
18         to_field_name="id",   #html中的value的值的對應字段,通常狀況下只用id
19         empty_label="請選擇用戶類型",  #默認空顯示內容
20         )
21 
22 
23 ##ModelChoiceField必須跟model中的__str__函數想結合使用:
24 class UserType(models.Model):
25     type_name = models.CharField(max_length=32)
26 
27     def __str__(self):  #必須跟__str__這個函數結合使用
28         return self.type_name
29 
30 
31 
32 
33 
34 #view.py
35 
36 def index(request):
37 
38     from app01.forms import UserForm
39     obj = UserForm()
40 
41     return render(request,'index.html',{'obj':obj})
42 
43 
44 #HTML
45 <body>
46     <p>{{ obj.user_type3 }}</p>
47 </body>
方式2、ModelChoiceField

三、Form內置鉤子進行驗證:django

django form中還預留了鉤子,主要有三個類型的鉤子:_clean_fields (單個字段驗證,,如:登陸頁面user or password字段)、_clean_fields (總體驗證,如:登陸頁面總體)、_post_clean(預留的鉤子,主要坐收尾工做)json

3.一、_clean_fields 

 1 from app01 import models
 2 from django.core.exceptions import ValidationError  #源碼裏面拋出的異常
 3 class RegisterForm(forms.Form):
 4     user = fields.CharField()   #下面的方法要想執行,先經過這邊正則驗證
 5     email = fields.EmailField()
 6      #根據源碼,咱們知道在咱們本身自定義的form中,是 定義clean_字段名 方法,去驗證,而後賦值給 cleaned_data
 7     #clean_%s 這個函數必需要有返回值,賦值給self.cleaned_data['%s']
 8     def clean_user(self):
 9         #註冊的時候,若是存在此用戶,則報錯,沒有,則繼續執行
10         c = models.User.objects.filter(name=self.cleaned_data['user'].count())
11         if not c:
12             return self.cleaned_data['user']
13         else:
14             raise ValidationError('用戶名已經存在',code="xxxx")  #存在就包異常
15  
16  
17     def clean_email(self):
18  
19         return self.cleaned_data['email']  #這邊必須返回一個值
clean_fields 單個字段驗證

3.二、_clean_form 

 1 from app01 import models
 2 from django.core.exceptions import ValidationError  #源碼裏面拋出的異常
 3 class RegisterForm(forms.Form):
 4     user = fields.CharField()   #下面的方法要想執行,先經過這邊正則驗證
 5     pwd = fields.CharField()
 6  
 7  
 8     def clean(self):
 9         c = models.User.objects.filter(name=self.cleaned_data['user'],pwd=self.cleaned_data['pwd']).count()
10         if not c:
11             return self.cleaned_data  #這邊必須有一個返回值,由於源碼裏面有返回值
12         else:
13             raise ValidationError("用戶名或密碼錯誤",code="xxxxx")  #這個異常應該給總體,不該該給某一個字段
clean_form from總體驗證

3.三、單個字段錯誤提示和form總體錯誤提示

1 obj.errors:
2         {
3             #self._clean_form() 返回的錯誤信息,也就是總體返回的錯誤信息,有的地方寫成: NON_FIFLD_ERRORS:[],其實就是代指的__all__
4             '__all__':[],
5             # clean_user和clean_pwd返回的錯誤信息,就是單個驗證返回的錯誤信息
6             'user':[{'code':"required",'message':'xxxx'}],
7             'pwd':[{'code':"required",'message':'xxxx'}]
8         }
錯誤提示定義

四、自定義驗證規則:

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'郵箱'}))
方式二
# 自定義方法
from django import forms
    from django.forms import fields
    from django.forms import widgets
    from django.core.exceptions import ValidationError
    from django.core.validators import RegexValidator
 
    class FInfo(forms.Form):
        username = fields.CharField(max_length=5,
                                    validators=[RegexValidator(r'^[0-9]+$', 'Enter a valid extension.', 'invalid')], )
        email = fields.EmailField()
 
        def clean_username(self):
            """
            Form中字段中定義的格式匹配完以後,執行此方法進行驗證
            :return:
            """
            value = self.cleaned_data['username']
            if "666" in value:
                raise ValidationError('666已經被玩爛了...', 'invalid')
            return value
方式三
#同時生成多個標籤進行驗證
from django.forms import Form
from django.forms import widgets
from django.forms import fields
 
from django.core.validators import RegexValidator
 
 
############## 自定義字段 ##############
class PhoneField(fields.MultiValueField):
    def __init__(self, *args, **kwargs):
        # Define one message for all fields.
        error_messages = {
            'incomplete': 'Enter a country calling code and a phone number.',
        }
        # Or define a different message for each field.
        f = (
            fields.CharField(
                error_messages={'incomplete': 'Enter a country calling code.'},
                validators=[
                    RegexValidator(r'^[0-9]+$', 'Enter a valid country calling code.'),
                ],
            ),
            fields.CharField(
                error_messages={'incomplete': 'Enter a phone number.'},
                validators=[RegexValidator(r'^[0-9]+$', 'Enter a valid phone number.')],
            ),
            fields.CharField(
                validators=[RegexValidator(r'^[0-9]+$', 'Enter a valid extension.')],
                required=False,
            ),
        )
        super(PhoneField, self).__init__(error_messages=error_messages, fields=f, require_all_fields=False, *args,
                                         **kwargs)
 
    def compress(self, data_list):
        """
        當用戶驗證都經過後,該值返回給用戶
        :param data_list:
        :return:
        """
        return data_list
 
############## 自定義插件 ##############
class SplitPhoneWidget(widgets.MultiWidget):
    def __init__(self):
        ws = (
            widgets.TextInput(),
            widgets.TextInput(),
            widgets.TextInput(),
        )
        super(SplitPhoneWidget, self).__init__(ws)
 
    def decompress(self, value):
        """
        處理初始值,當初始值initial不是列表時,調用該方法
        :param value:
        :return:
        """
        if value:
            return value.split(',')
        return [None, None, None]
方式四

五、Form內置序列化錯誤信息:

  1 #form.py
  2 rom django import forms
  3 from django.forms import fields,widgets
  4 
  5 class LoginForm(forms.Form):
  6     username = fields.CharField() #這跟login.html中的input標籤的name屬性的值一致
  7     password = fields.CharField(
  8         max_length=64,
  9         min_length=12
 10     )
 11 
 12 
 13 
 14 
 15 
 16 
 17 #view 中的login 函數
 18 #第一種 使用ErrorDict中的as_json函數,不過在HTML中相應獲取錯誤信息須要反解兩次
 19 from django.shortcuts import render,HttpResponse
 20 import json
 21 def login(request):
 22     ret = {'status':True,'error':None,'data':None}
 23     if request.method == "GET":
 24         return render(request,'login.html')
 25     elif request.method == "POST":
 26         obj = LoginForm(request.POST)
 27         if obj.is_valid():
 28             print(obj.cleaned_data)
 29         else:
 30             # print(type(obj.errors)) 經過打印類型得知是屬於ErrorDict
 31             from django.forms.utils import ErrorDict  #經過源碼得知:as_data 返回的是原生的字典,as_json()是相似json格式的字符串
 32             ret['error'] = obj.errors.as_json()
 33         return HttpResponse(json.dumps(ret))  #由於as_json()和json.dumps 至關於序列化了兩次
 34 
 35 
 36 
 37 #第二張自定義JsonCustomEncoder類
 38 from django.core.exceptions import ValidationError
 39 import json
 40 class JsonCustomEncoder(json.JSONEncoder):  #直接在cls=JsonCustomEncoder類名,去序列化複雜的數據類型
 41     def default(self,field):
 42         if isinstance(field,ValidationError):  #
 43             # # from django.core.exceptions import ValidationError  #看一下這個異常,發現field的字段和錯誤信息都保存在這個ValidationError對象裏
 44             return {'code':field.code,'messages':field.messages}
 45         else:
 46             return json.JSONEncoder.default(self,field)
 47 
 48 
 49 
 50 from django.shortcuts import render,HttpResponse
 51 import json
 52 
 53 def login(request):
 54     ret = {'status':True,'error':None,'data':None}
 55     if request.method == "GET":
 56         return render(request,'login.html')
 57     elif request.method == "POST":
 58         obj = LoginForm(request.POST)
 59         if obj.is_valid():
 60             print(obj.cleaned_data)
 61         else:
 62             ret['error'] = obj.errors.as_data()
 63             # for k,v in obj.errors.as_data().items():
 64             #     print(k,v)    經過打印發現as_data後 value是一個ValidationError對象
 65             # ret = {'k1':'v1','k2':ValueError()}  #像這種複雜數據類型,json是不能序列化的,咱們只能作局部處理
 66 #這邊cls 是序列化的時候,對每個字段序列化的時候,都會調用一個它的default方法,所以重寫JsonCustomEncoder類中default方法來進行復雜狀況下的序列化操做
 67         result = json.dumps(ret,cls=JsonCustomEncoder)
 68         return HttpResponse(result)
 69 
 70 
 71 
 72 
 73 #HTML
 74 """
 75 <body>
 76     <form id="fm">
 77         {% csrf_token %}
 78         <p><input type="text" name="username" /></p>  #這邊username 須要跟 from 裏面的字段 是如出一轍
 79         <p><input type="text" name="password" /></p>
 80         <a id="submit">提交</a>
 81     </form>
 82 
 83     <script src="/static/jquery-1.12.4.js"></script>
 84     <script>
 85         $(function(){
 86             $('#submit').click(function(){
 87                 $.ajax({
 88                     url:'/login/',
 89                     type:'post',
 90                     data:$('#fm').serialize(),
 91                     sucess:function(arg){
 92                         //console.log(arg);
 93                         arg = JSON.parse(arg);
 94                         console.log(arg)
 95                     },
 96                     error:function(){
 97 
 98                     }
 99                 })
100             })
101         })
102     </script>
103 </body>"""
104 
105 
106 
107 
108 #返回的數據類型爲:  
109 
110 "{\"data\": null, \"status\": true, \"error\": {\"username\": [{\"code\": \"required\", \"messages\": [\"This field is required.\"]}],
111  \"password\": [{\"code\": \"required\", \"messages\": [\"This field is required.\"]}]}}"
序列化錯誤信息的兩種方式

六、Form類中的fields、widgets 簡單示例:

a、Form類:

from django import forms  # 導入forms
from django.forms import widgets  # 導入插件
from django.forms import fields   # 導入字段,之後對於像charField、EmailField等字段格式的處理不須要在經過form.進行定義了,而是經過fields進行定義

class FM(forms.Form):
    # 字段自己只作驗證
    user = fields.CharField(
        error_messages={'required': '用戶名不能爲空.'},  # 定義錯誤信息的提示語,required爲定義輸入框爲空的提示語
        # widget=widgets.Textarea(attrs={'class': 'c1'}),  # 導入插件中的多行文本輸入,並定義樣式
        label="用戶名",  # 定義標籤名稱
        )
    pwd = fields.CharField(
        max_length=12,  # 定義字符最大、最近小字符長度,及相應錯誤提示語
        min_length=6,
        error_messages={'required': '密碼不能爲空.', 'min_length': '密碼長度不能小於6', "max_length": '密碼長度不能大於12'},
        widget=widgets.PasswordInput(attrs={'class': 'c2'})  # 導入插件中的密碼非明文輸入,並定義樣式
    )
    email = fields.EmailField(error_messages={'required': '郵箱不能爲空.', 'invalid': "郵箱格式錯誤"})  # invalid定義輸入框無效是的提示語

    f = fields.FileField()  # 文件上傳

    p = fields.FilePathField(path='app01')  # 將路徑下的所有文件進行展現

    city1 = fields.ChoiceField(  # 單項選擇框
        choices=[(0, '上海'), (1, '廣州'), (2, '東莞')]
    )                                                                   
    city2 = fields.MultipleChoiceField(      # 多項選擇框
        choices=[(0, '上海'), (1, '廣州'), (2, '東莞')]
    )

b.views:

from app01 import models


def fm(request):
    if request.method == "GET":
        # 從數據庫中吧數據獲取到
        dic = {
            "user": 'r1',
            'pwd': 'password',
            'email': 'email@163.com',
            'city1': 1,
            'city2': [1, 2]
        }
        obj = FM(initial=dic)  # 初始化操做,經過字典形式傳遞默認值
        return render(request, 'fm.html', {'obj': obj})
    elif request.method == "POST":
        obj = FM(request.POST)
        r1 = obj.is_valid()
        if r1:
            # obj.cleaned_data
            print(obj.changed_data)
            # models.UserInf.objects.create(**obj.cleaned_data)
        else:
            # errors 繼承了ErrorDict類
            print(obj.errors.as_json())
            # print(obj.errors['user'][0])
            return render(request, 'fm.html', {'obj': obj})
    return redirect('http://www.ww.qq.com')

c、HTML:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title></title>
</head>
<body>
    <form action="/fm/" method="POST">
        {% csrf_token %}
        <p>{{ obj.user.label}}{{ obj.user }} {{ obj.errors.user.0 }}</p>  <!-- 相似於view視圖中的 obj.errors['user'][0]-->
        <p>{{ obj.pwd }} {{ obj.errors.pwd.0 }}</p>
        <p>{{ obj.email }}{{ obj.errors.email.0 }}</p>
        <p>{{ obj.f}}</p>
        <p>{{ obj.p}}</p>
        <p>{{ obj.city1}}</p>
        <p>{{ obj.city2}}</p>
        <input type="submit" value="提交" />
    </form>
</body>
</html>
相關文章
相關標籤/搜索