django之form組件

一 建立一個form組件css

 導入forms模塊組件:from django import formshtml

 建立組件:建立一個類繼承者forms.Form這個類git

 類型:正則表達式

  CharField:字符串類型,min_length:字符長度不能小於多少;max_length:字符的長度不能大於多少,error_messages:能夠根據保存信息顯示對應的中文報錯,required:該字段不可以爲空,widget:對input標籤操做。數據庫

  IntegerField:整數類型,invalid:格式錯誤django

  MultiplechioceField:設置字段爲多選框(單選框)。initial=[數字,]:初始個數。choices=((value,數據),(value,數據)):爲多選框(單選框賦值)。widgets.CheckboxSelectMultiple:設置爲複選框bootstrap

 其餘類型:app

Field
    required=True,               是否容許爲空
    widget=None,                 HTML插件
    label=None,                  用於生成Label標籤或顯示內容
    initial=None,                初始值
    help_text='',                幫助信息(在標籤旁邊顯示)
    error_messages=None,         錯誤信息 {'required': '不能爲空', 'invalid': '格式錯誤'}
    show_hidden_initial=False,   是否在當前插件後面再加一個隱藏的且具備默認值的插件(可用於檢驗兩次輸入是否一直)
    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-01
TimeField(BaseTemporalField)    格式:11:12
DateTimeField(BaseTemporalField)格式:2015-09-01 11:12
 
DurationField(Field)            時間間隔:%d %H:%M:%S.%f
    ...
 
RegexField(CharField)
    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類型
    ...
View Code

 根據不一樣要求爲表單加上不一樣的屬性值:導入from django.forms impost widgetside

  widgets.PasswoedInput:加上密文的屬性值,addrs:爲指定的標籤加上屬性。函數

  widgets.TextInput:文本信息

  widgets.Select:下拉菜單,choices:爲option出入值和value屬性值

 鉤子clean:首先導入異常:from django.core.exceptions import ValidationError。

  局部鉤子:clean_字段名,就是使用clean_加上一個字段名。用於字段校驗

    raise calidationsError:拋出錯誤信息

    cleaned_data:若是符合條件,數據就會存放在這裏面,可使用get獲取是一個有序的字典格式,從上往下依次判斷添加。

 for name, field in self.fields.items():
              try:

                    value = field.clean(value)
                    self.cleaned_data[name] = value
                    if hasattr(self, 'clean_%s' % name):
                        value = getattr(self, 'clean_%s' % name)()
                        self.cleaned_data[name] = value
              except ValidationError as e:
                    self.add_error(name, e)

  全局鉤子:clean,直接在這個函數裏面定義功能,能夠用於多個字段的操做和比較,直接能夠獲取cleaned_data裏面的數據。

    __all__:全局拋出來的錯誤存放在這個裏面的。

        self.clean()     # def self.clean():return self.cleaned_data
        return  not self.errors    # True或者False    
from django import forms
from django.forms import widgets
from django.core.exceptions import ValidationError


class LoginForm(forms.Form):

    user=forms.CharField(min_length=5,max_length=12,
                         error_messages={
                              "required":"該字段不能爲空",
                              "min_length":"該字段的長度不能小於5",
                              "max_length":"該字段的長度不能大於12"},
                         widget=widgets.TextInput(attrs={"class":"form-control"})
                         )


    pwd=forms.CharField(
        error_messages={
            "invalid": "必須是數字"
        },
        widget=widgets.PasswordInput(attrs={"class":"form-control",})
    )

    gender=forms.CharField(
        widget=widgets.Select(choices=((1,''),(0,''),))
    )

    usersss = forms.MultipleChoiceField(
        initial=[2, ],
        choices=((1, '上海'), (2, '北京'),),
        widget=widgets.CheckboxSelectMultiple
    )


    def clean_user(self):
       print("============",self.cleaned_data.get("pwd"))  # ============ None
       if  not self.cleaned_data.get("user").isdigit():

           return self.cleaned_data.get("user")
       else:
           raise ValidationError("該字段不能是純數字")



    def clean_pwd(self):
        print("-----------------",self.cleaned_data.get("user"))
        import re
        val=self.cleaned_data.get("pwd")
        ret=re.findall("^\d{6}yuan$",val)
        if ret:
            return val
        else:
            raise ValidationError("密碼不符合設定要求")

    def clean(self):


        if self.cleaned_data.get("user") and self.cleaned_data.get("pwd"):
            if self.cleaned_data.get("user") != self.cleaned_data.get("pwd"):
                return self.cleaned_data

            else:
                raise ValidationError("用戶名與密碼不能一致!")

        return self.cleaned_data
View Code

 django內置插件:

TextInput(Input)
NumberInput(TextInput)
EmailInput(TextInput)
URLInput(TextInput)
PasswordInput(TextInput)
HiddenInput(TextInput)
Textarea(Widget)
DateInput(DateTimeBaseInput)
DateTimeInput(DateTimeBaseInput)
TimeInput(DateTimeBaseInput)
CheckboxInput
Select
NullBooleanSelect
SelectMultiple
RadioSelect
CheckboxSelectMultiple
FileInput
ClearableFileInput
MultipleHiddenInput
SplitDateTimeWidget
SplitHiddenDateTimeWidget
SelectDateWidget
View Code

 經常使用選擇插件:

# 單radio,值爲字符串
# user = fields.CharField(
#     initial=2,
#     widget=widgets.RadioSelect(choices=((1,'上海'),(2,'北京'),))
# )
 
# 單radio,值爲字符串
# user = fields.ChoiceField(
#     choices=((1, '上海'), (2, '北京'),),
#     initial=2,
#     widget=widgets.RadioSelect
# )
 
# 單select,值爲字符串
# user = fields.CharField(
#     initial=2,
#     widget=widgets.Select(choices=((1,'上海'),(2,'北京'),))
# )
 
# 單select,值爲字符串
# user = fields.ChoiceField(
#     choices=((1, '上海'), (2, '北京'),),
#     initial=2,
#     widget=widgets.Select
# )
 
# 多選select,值爲列表
# user = fields.MultipleChoiceField(
#     choices=((1,'上海'),(2,'北京'),),
#     initial=[1,],
#     widget=widgets.SelectMultiple
# )
 
 
# 單checkbox
# user = fields.CharField(
#     widget=widgets.CheckboxInput()
# )
 
 
# 多選checkbox,值爲列表
# user = fields.MultipleChoiceField(
#     initial=[2, ],
#     choices=((1, '上海'), (2, '北京'),),
#     widget=widgets.CheckboxSelectMultiple
# )
View Code

二 實例form對象

實例化時:
        self.fields={
            "username":"字段規則對象",
            "password":"字段規則對象",

        }

 LoginForm:form自建實例的對象存放的地點,request.POST:將數據傳遞給對應的字段,綁定數據的表單實例

 is_valid:校驗,將檢驗是否符合要求,返回的是一個布爾值

  cleaned_data:檢驗正確數據就存放在這裏面,是以字典的格式存放的,出數據。

  errors:檢驗沒有經過或錯誤的信息存放在這個裏面,是以字典的格式存放的。errors.get獲取裏面的某些數據。

from django.shortcuts import render,HttpResponse

# Create your views here.

from django import forms
from .models import *

from django.forms import widgets

from .forms import *



def login(request):
    if request.method=="POST":
        #print(request.POST) #<QueryDict: {'csrfmiddlewaretoken': ['0xrifjX7jplIZwngbrRjpHPXw6kyDVa2Erca0sGYfjH9UuDfHzNUdMzlh7EH2v44'], 'user': ['asdas'], 'pwd': ['12321321']}>
        login_form=LoginForm(request.POST) # 將數據傳給對應字段  綁定數據的表單實例

        '''
            #   self.cleaned_data={"pwd":"12312412"}      
            #   self.errors={"user":"yuan",}
        '''
        if login_form.is_valid():
            print("經過驗證")
            print(login_form.cleaned_data)
            print("use:",login_form.cleaned_data.get("user"))
            print(login_form.errors)
            ###############
            # user=login_form.cleaned_data.get("user")
            # pwd=login_form.cleaned_data.get("pwd")
            # UserInfo.objects.filter(username=user,password=pwd)
            # UserInfo.objects.filter(**login_form.cleaned_data)

            return HttpResponse("OK")
        else:
            # print("驗證失敗")
            # print(login_form.cleaned_data) # {'pwd': 77777}
            # print(login_form.errors)
            # ################## login_form.errors是什麼類型
            # print(type(login_form.errors))# <class 'django.forms.utils.ErrorDict'>
            # ###################獲取login_form.errors的某個鍵的值
            # print(login_form.errors.get("user"))
            # print(type(login_form.errors.get("pwd")))# <class 'django.forms.utils.ErrorList'>
            #
            # #login_form.errors={"user":["小於5位","不是數字"],"pwd":["",""]}
            errors=login_form.errors# {"user":["該字段不能是純數字",],"pwd":["",""]}
            print("errors-->",errors)

            error_all=errors.get("__all__")
            return render(request, "login.html", {"login_form": login_form,"errors":errors,"error_all":error_all})

    #### get請求

    login_form=LoginForm()   # form組件的實例對象   未綁定表單實例
    return render(request,"login.html",{"login_form":login_form})
View Code

三 html文件渲染

 模板導入input標籤:直接用對象.字段取出內容  {{ 對象.字段}}

 模板導入錯誤信息:直接使用srrors.字段名.0取出數據{{ srrors.字段名.0 }}

 form組件只可以直接渲染input標籤,form標籤仍是須要本身寫的。

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <!-- 新 Bootstrap 核心 CSS 文件 -->
    <link rel="stylesheet" href="//cdn.bootcss.com/bootstrap/3.3.5/css/bootstrap.min.css">
    <style>
        .container{
            margin-top: 100px;

        }
    </style>
</head>
<body>


<div class="container">
    <div class="row">
        <div class="col-md-6">

            <form action="/login/" method="post">
                 {% csrf_token %}
                  <div class="form-group">
                    <label for="user">user</label>
                    {{ login_form.user }} <span>{{ errors.user.0 }}</span>
                  </div>
                  <div class="form-group">
                    <label for="pwd">pwd</label>
                    {{ login_form.pwd }} <span>{{ errors.pwd.0 }}</span>
                  </div>
                   <div class="form-group">
                    <label for="gender">gender</label>
                    {{ login_form.gender }}<span>{{ error_all.0 }}</span>
                  </div>

                 <p>{{ login_form.usersss }}</p>

                  <button type="submit" class="btn btn-default">Submit</button>
                </form>
            <hr>
{#            <form action="">#}
{#                {{ login_form.as_p }}#}
{#            </form>#}

        </div>
    </div>
</div>

</body>
</html>
View Code

四 其餘渲染對象

對於<label>/<input> 對,還有幾個輸出選項:

  • {{ form.as_table }} 以表格的形式將它們渲染在<tr> 標籤中
  • {{ form.as_p }} 將它們渲染在<p> 標籤中
  • {{ form.as_ul }} 將它們渲染在<li> 標籤中

注意,你必須本身提供<table> 或<ul> 元素。

{{ form.as_p }}結果以下:

<form action="">
    <p>
        <label for="id_username">Username:</label>
        <input id="id_username" maxlength="100" name="username" type="text" required="">
    </p>
 
 
    <p>
        <label for="id_password">Password:</label>
        <input id="id_password" maxlength="100" name="password" placeholder="password" type="password" required="">
    </p>
 
 
    <p>
        <label for="id_telephone">Telephone:</label> <input id="id_telephone" name="telephone" type="number" required="">
    </p>
 
 
    <p>
        <label for="id_email">Email:</label> <input id="id_email" name="email" type="email" required="">
    </p>
 
 
    <p>
        <label for="id_is_married">Is married:</label> <input id="id_is_married" name="is_married" type="checkbox">
    </p>
 
 
    <input type="submit" value="註冊">
</form>
View Code

 這種渲染有了限制,不能個自定義的渲染,而是將全部的字段所有渲染過去。

手動渲染:咱們沒有必要非要讓Django 來分拆表單的字段;若是咱們喜歡,咱們能夠手工來作每一個字段都是表單的一個屬性,可使用{{ form.name_of_field }} 訪問,並將在Django 模板中正確地渲染

<div class="fieldWrapper">
    {{ form.Username.errors }}
    {{ form.Username.label_tag }}
    {{ form.Username }}
</div>

 五 表單渲染的錯誤信息

registerForm=RegisterForm(request.POST)
print(type(registerForm.errors))                      #<class 'django.forms.utils.ErrorDict'>
print(type(registerForm.errors["username"]))          #<class 'django.forms.utils.ErrorList'> 
使用{{ form.name_of_field.errors }} 顯示錶單錯誤的一個清單,並渲染成一個ul。看上去可能像:
<ul class="errorlist">
    <li>Sender is required.</li>
</ul>

 

 

補充練習:

from django.shortcuts import render

# Create your views here.
from .models import UserInfor

from django.forms import ModelForm
from django import forms

from .models import *

print(City.objects.all().values_list("id","name"))

# class RegForm(forms.Form):
#     user = forms.CharField(max_length=32)
#     #gender_tuple=(0,'上海'),(1,'北京'),(2,'保定')
#     gender = forms.ChoiceField(choices =City.objects.all().values_list("id","name"))
#
#     def __init__(self,*args,**kwargs):
#         super(RegForm,self).__init__(*args,**kwargs)
#         #print("Ok")
#         print(self.fields["gender"].choices)
#         self.fields["gender"].choices=City.objects.all().values_list("id","name")


'''
class UserInfor(models.Model):
    user=models.CharField(max_length=32)
    gender=models.IntegerField(choices=((1,"男"),(2,"女")))
    city=models.ForeignKey("City",default=1)
    roles=models.ManyToManyField("Roles",default=1)
|||||

class UserInfor(forms.Form):
    user=forms.CharField()
    gender=forms.TypedChoiceField(choices=((1,"男"),(2,"女")))
    city=forms.ModelChoiceField(choices=City.objects.all())
    roles=forms.ModelMultipleChoiceField(choices=Roles.objects.all())
'''

class RegForm(ModelForm):
    class Meta:
        model=UserInfor
        fields="__all__"

def reg(reqeust):
    form=RegForm()
    print(form.fields)

    return render(reqeust,"reg.html",{"form":form})
View Code
相關文章
相關標籤/搜索