Django中的Form組件

一、form組件的主要功能:

  • 生成頁(yè)面的HTML標(biāo)簽及樣式
  • 對(duì)用戶提交的數(shù)據(jù)進(jìn)行校驗(yàn)
  • 自動(dòng)生成錯(cuò)誤信息
  • 保留上次輸入信息

二、使用form組件實(shí)現(xiàn)注冊(cè)功能

1、在Django項(xiàng)目下創(chuàng)建一個(gè)文件夾,在文件夾中創(chuàng)建一個(gè)朋友文件,名字隨便起,之后在py文件中寫(xiě)一個(gè)RegisterForm類:
from django import forms
from django.core.validators import RegexValidator
from django.core.exceptions import ValidationError

class RegisterForm(forms.Form):#類必須繼承forms.Form
    # 用戶名
    username = forms.CharField(
        min_length=6,#設(shè)置最小長(zhǎng)度
        max_length=12,#設(shè)置最大長(zhǎng)度
        label="用戶名",#設(shè)置標(biāo)簽名
        #錯(cuò)誤信息提示設(shè)置
        error_messages={
            "min_length": "用戶名不能少于6位",
            "max_length":'用戶名不能超過(guò)12位',
            "required": "用戶名不能為空"
        },
        #插件設(shè)置
        widget=forms.widgets.TextInput(
            attrs={"class": "form-control"}# 給生成的標(biāo)簽添加屬性
        )
    )
    # 電話號(hào)碼
    phone = forms.CharField(
        label="手機(jī)號(hào)",
        error_messages={
            "required": "手機(jī)號(hào)不能為空"
        },
        # 調(diào)用Form組件中的驗(yàn)證器來(lái)校驗(yàn)手機(jī)號(hào)
        validators=[RegexValidator(r'1[1-9][0-9]{9}','手機(jī)號(hào)格式不正確')],
        widget=forms.widgets.TextInput(
            attrs={'class': 'form-control'},  # 給生成的標(biāo)簽添加類屬性
        )
    )
    # 密碼
    password = forms.CharField(
        label="密碼",
        min_length=6,
        error_messages={
            "required": "密碼不能為空",
            'min_length':'密碼不能少于6位'
        },
        widget=forms.widgets.PasswordInput(
            attrs={'class': 'form-control'},  # 給生成的標(biāo)簽添加屬性
            render_value=True  # 返回報(bào)錯(cuò)信息的時(shí)候要不要展示密碼
        )
    )
    # 二次密碼校驗(yàn)
    re_password = forms.CharField(
        label="確認(rèn)密碼",
        min_length=6,
        error_messages={
            "required": "確認(rèn)密碼不能為空",
            'min_length':'確認(rèn)密碼不能少于六位'
        },
        widget=forms.widgets.PasswordInput(
            attrs={'class': 'form-control'},  # 給生成的標(biāo)簽添加屬性
            render_value=True  # 返回報(bào)錯(cuò)信息的時(shí)候要不要展示密碼
        )
    )
    # 郵箱
    email = forms.CharField(
        label="郵箱",
        error_messages={
            "required": "郵箱不能為空",
        },
        # 調(diào)用Form組件中的驗(yàn)證器來(lái)校驗(yàn)郵箱
        validators=[RegexValidator(r'^[a-zA-Z0-9_.-]+@[a-zA-Z0-9-]+(\.[a-zA-Z0-9-]+)*\.[a-zA-Z0-9]{2,6}$', "郵箱格式不正確")],
        widget=forms.widgets.TextInput(
            attrs={'class': 'form-control'},  # 給生成的標(biāo)簽添加屬性
        )
    )
    # 通過(guò)自定義一個(gè)clean_字段名的方法實(shí)現(xiàn)對(duì)Form表單特定字段的校驗(yàn)
    def clean_username(self):
        # 從cleaned_data中取出想要的數(shù)據(jù)
        value = self.cleaned_data.get("username")
        if "金瓶梅" in value:
            # 錯(cuò)誤就拋異常
            raise ValidationError("不符合社會(huì)主義核心價(jià)值觀!")
        else:
            return value

    # 通過(guò)Form表單的全局鉤子函數(shù)來(lái)驗(yàn)證兩次輸入的密碼是否正確
    # 該clean方法, 在每個(gè)字段都校驗(yàn)通過(guò)之后才調(diào)用執(zhí)行
    def clean(self):
        password = self.cleaned_data.get('password')
        re_password = self.cleaned_data.get('re_password')
        if re_password and password == re_password:
            # 判斷正確就返回校驗(yàn)過(guò)后的數(shù)據(jù)
            return self.cleaned_data
        else:
            # 添加錯(cuò)誤到add_error
            self.add_error('re_password','兩次密碼不一致,請(qǐng)重新輸入')
            # 主動(dòng)拋出異常
            raise ValidationError('兩次密碼不一致,請(qǐng)重新輸入')

2、url的書(shū)寫(xiě):
url(r'^register/', views.Register.as_view())#CBV方式寫(xiě)視圖函數(shù),
3、views中的視圖函數(shù):
from django.http import JsonResponse, HttpResponse
from django import views
from blog.myforms.forms import LoginForm, RegisterForm

class Register(views.View):  # 必須繼承views.View
    # get請(qǐng)求方式
    def get(self, request):
        # 用自定義的Form類實(shí)例化一個(gè)對(duì)象,用于前端頁(yè)面生成標(biāo)簽
        register_obj = RegisterForm()
        return render(request, 'register.html', {'register_obj': register_obj})

    # post請(qǐng)求方式
    def post(self, request):
        # 前后端交互信息
        res = {'code': 0}
        # 實(shí)例化form類,將前端得到的數(shù)據(jù)提交到實(shí)例中
        register_obj = RegisterForm(request.POST)
        # 利用form內(nèi)置方法校驗(yàn)前端得到的數(shù)據(jù)
        if register_obj.is_valid():
            # 從數(shù)據(jù)庫(kù)中查詢用戶輸入的用戶名,手機(jī)號(hào),郵箱是否重復(fù)
            username = models.UserInfo.objects.filter(username=request.POST.get('username'))
            phone = models.UserInfo.objects.filter(phone=request.POST.get('phone'))
            email = models.UserInfo.objects.filter(email=request.POST.get('email'))
            if username:
                res['code'] = 1
                res['msg'] = '用戶名已存在,請(qǐng)重新輸入'
            elif phone:
                res['code'] = 2
                res['msg'] = '您輸入的手機(jī)號(hào)已存在,請(qǐng)重新輸入'
            elif email:
                res['code'] = 3
                res['msg'] = '您輸入的郵箱號(hào)已存在,請(qǐng)重新輸入'
            else:
                # 數(shù)據(jù)正確后剔除re_password中的數(shù)據(jù)
                register_obj.cleaned_data.pop("re_password")
                # 得到前端的頭像文件,文件和圖片數(shù)據(jù)存放在request.FILES中
                avatar_file = request.FILES.get('avatar_file')
                # 通過(guò)數(shù)據(jù)庫(kù)操作創(chuàng)建user
                models.UserInfo.objects.create_user(**register_obj.cleaned_data, avatar=avatar_file)
                # 返回前端頁(yè)面要跳轉(zhuǎn)的url
                res['msg'] = '/login/'
        else:
            res['code'] = 4
            # 錯(cuò)誤信息
            res['msg'] = register_obj.errors
        return JsonResponse(res)
4、register.html
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>用戶注冊(cè)</title>
    <link rel="stylesheet" href="/static/bootstrap/bootstrap-3.3.7/css/bootstrap.min.css">
    <link rel="stylesheet" href="/static/css/mycss.css">
</head>
<body>
<div class="container" style="margin-top: 50px">
    <div class="row">
        <div class="col-lg-6 col-lg-offset-3">
            <div class="panel panel-info" style="border: none">
                <div class="panel-heading text-center">
                    <h4>用戶注冊(cè)</h4>
                </div>
                <div class="panel-bady">
                    <form>
                        {% csrf_token %}
                        {% for field in register_obj %}
                            <div class="form-group">
                                <label class="letleft" for="field.id_for_label">{{ field.label }}</label>
                                {{ field }}
                                <span class="err-msg"></span>
                            </div>
                        {% endfor %}
                        <div class="form-group">
                            <label for="avatar">用戶頭像<img id="avatar-img" src="/media/avatars/default.png" alt="用戶頭像"
                                                         style="height: 80px;width: 80px;margin-left: 15px"></label>
                            <input type="file" accept="image/*" id="avatar" style="display: none;">
                            <button type="button" id="register-btn" class="btn btn-success letleft">提交</button>
                        </div>
                        <div id="popup-captcha"></div>
                    </form>
                </div>
            </div>
        </div>
    </div>
</div>

<script src="/static/js/jquery-3.3.1.js"></script>
<script>
    $(function () {
        $("#register-btn").click(function () {
            //ajax提交數(shù)據(jù)時(shí),當(dāng)有文件或者圖片時(shí),需要借助FormData對(duì)象來(lái)實(shí)現(xiàn)數(shù)據(jù)前后端交互,F(xiàn)ormData
            // 相當(dāng)于是一個(gè)打包數(shù)據(jù)的工具,將需要傳輸?shù)臄?shù)據(jù)通過(guò)append方法以鍵值對(duì)的方式添加到FormData對(duì)象中
            let formdata = new FormData();
            formdata.append('username', $('#id_username').val());
            formdata.append('phone', $('#id_phone').val());
            formdata.append('password', $('#id_password').val());
            formdata.append('re_password', $('#id_re_password').val());
            formdata.append('email', $('#id_email').val());
            //設(shè)置csrftoken來(lái)防止跨站csrf攻擊
            formdata.append('csrfmiddlewaretoken', $("[name='csrfmiddlewaretoken']").val());
            //通過(guò)jquery對(duì)象獲取文件需要將jquery對(duì)象轉(zhuǎn)化成js對(duì)象再調(diào)用js對(duì)象的files方法
            formdata.append('avatar_file', $("#avatar")[0].files[0]);
            $.ajax({
                url: '/register/',
                type: 'post',
                processData: false,   //不讓jQuery處理我的obj
                contentType: false,  // 不讓jQuery設(shè)置請(qǐng)求的內(nèi)容類型
                data: formdata,
                success: function (res) {
                    if (res.code === 0) {
                        location.href = res.msg
                    }
                    if (res.code === 1) {
                        $('#id_username').next().text(res.msg)
                    }
                    if (res.code === 2) {
                        $('#id_phone').next().text(res.msg)
                    }
                    if (res.code === 3) {
                        $('#id_email').next().text(res.msg)
                    }
                    if (res.code === 4) {
                        $.each(res.msg, function (k, v) {
                            //添加錯(cuò)誤提示樣式
                            $("#id_" + k).next().text(v[[0]]).parent().addClass('err-msg')

                        })
                    }
                }
            });
        });
        // 前端頁(yè)面實(shí)現(xiàn)頭像預(yù)覽
        // 當(dāng)用戶選中文件之后,也就是頭像的input標(biāo)簽有值時(shí)觸發(fā)
        $("#avatar").change(function () {
            // 找到用戶選中的那個(gè)文件
            let file = this.files[0];
            // 生成一個(gè)讀文件的對(duì)象
            let fr = new FileReader();
            // 從文件中讀取頭像文件數(shù)據(jù)
            fr.readAsDataURL(file);
            // 等到讀完之后
            fr.onload = function () {
                // 將頭像img標(biāo)簽的src屬性更換成我選中的那個(gè)文件
                $("#avatar-img").attr("src", fr.result)
            }
        });

        //input標(biāo)簽聚焦清空樣式
        $('input').focus(function () {
            $(this).next().text('').parent().removeClass('err-msg')
        });

    })
</script>

</body>
</html>

三、Form組件常用字段與插件介紹

創(chuàng)建Form類時(shí),主要涉及到 【字段】 和 【插件】,字段用于對(duì)用戶請(qǐng)求數(shù)據(jù)的驗(yàn)證,插件用于自動(dòng)生成HTML;

1、initial

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

class LoginForm(forms.Form):
    username = forms.CharField(
        min_length=8,
        label="用戶名",
        initial="王飛"  # 設(shè)置默認(rèn)值
    )
    pwd = forms.CharField(min_length=6, label="密碼")
2、error_messages

重寫(xiě)錯(cuò)誤信息。

class LoginForm(forms.Form):
    username = forms.CharField(
        min_length=8,
        label="用戶名",
        initial="張三",
        error_messages={
            "required": "不能為空",
            "invalid": "格式錯(cuò)誤",
            "min_length": "用戶名最短8位"
        } )
    pwd = forms.CharField(min_length=6, label="密碼")
3、password
class LoginForm(forms.Form):
    pwd = forms.CharField(
        min_length=6,
        label="密碼",
        widget=forms.widgets.PasswordInput(attrs={'class': 'c1'}, render_value=True)
    )
4、radioSelect(生成的是input標(biāo)簽)

單radio值為字符串

class LoginForm(forms.Form):
    gender = forms.fields.ChoiceField(
        choices=((1, "男"), (2, "女"), (3, "保密")),
        label="性別",
        initial=3,//默認(rèn)值
        widget=forms.widgets.RadioSelect()
    )
5、單選Select(生成select標(biāo)簽)
class LoginForm(forms.Form):
    hobby = forms.fields.ChoiceField(
        choices=((1, "籃球"), (2, "足球"), (3, "雙色球"), ),
        label="愛(ài)好",
        initial=3,
        widget=forms.widgets.Select()
    )
6、多選Select(生成的是select標(biāo)簽)
class LoginForm(forms.Form):
    hobby = forms.fields.MultipleChoiceField(
        choices=((1, "籃球"), (2, "足球"), (3, "雙色球"), ),
        label="愛(ài)好",
        initial=[1, 3],
        widget=forms.widgets.SelectMultiple()
    )
7、單選checkbox(生成的是input標(biāo)簽)
class LoginForm(forms.Form):
    keep = forms.fields.ChoiceField(
        label="是否記住密碼",
        initial="checked",
        widget=forms.widgets.CheckboxInput()
    )
8、多選checkbox(生成的是input標(biāo)簽)
class LoginForm(forms.Form):
        hobby = forms.fields.MultipleChoiceField(
        choices=((1, "籃球"), (2, "足球"), (3, "雙色球"),),
        label="愛(ài)好",
        initial=[1, 3],
        widget=forms.widgets.CheckboxSelectMultiple()
    )

關(guān)于radioSelect、單選Select、多選Select、單選checkbox、多選checkbox生成的標(biāo)簽的樣式區(qū)別如圖:

微信圖片_20180823205102.png

注意:關(guān)于choice的注意事項(xiàng):在使用選擇標(biāo)簽時(shí),需要注意choices的選項(xiàng)可以從數(shù)據(jù)庫(kù)中獲取,但是由于是靜態(tài)字段 獲取的值無(wú)法實(shí)時(shí)更新,那么需要自定義構(gòu)造方法從而達(dá)到此目的。
方式一:

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

 
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'].choices = ((1, '上海'), (2, '北京'),)
         //數(shù)據(jù)變成動(dòng)態(tài)的從數(shù)據(jù)庫(kù)中獲取
        self.fields['user'].choices = models.Classes.objects.all().values_list('id','caption')

方式二、

from django import forms
from django.forms import fields
from django.forms import models as form_model

 
class MyForm(forms.Form):
    authors = form_model.ModelMultipleChoiceField(queryset=models.NNewType.objects.all())  # 多選
    # authors = form_model.ModelChoiceField(queryset=models.NNewType.objects.all())  # 單選

四、django中所有Form表單內(nèi)置字段及屬性:

Field
    required=True,               是否允許為空
    widget=None,                 HTML插件
    label=None,                  用于生成Label標(biāo)簽或顯示內(nèi)容
    initial=None,                初始值
    help_text='',                幫助信息(在標(biāo)簽旁邊顯示)
    error_messages=None,         錯(cuò)誤信息 {'required': '不能為空', 'invalid': '格式錯(cuò)誤'}
    validators=[],               自定義驗(yàn)證規(guī)則
    localize=False,              是否支持本地化
    disabled=False,              是否可以編輯
    label_suffix=None            Label內(nèi)容后綴
 
 
CharField(Field)
    max_length=None,             最大長(zhǎng)度
    min_length=None,             最小長(zhǎng)度
    strip=True                   是否移除用戶輸入空白
 
IntegerField(Field)
    max_value=None,              最大值
    min_value=None,              最小值
 
FloatField(IntegerField)
    ...
 
DecimalField(IntegerField)
    max_value=None,              最大值
    min_value=None,              最小值
    max_digits=None,             總長(zhǎng)度
    decimal_places=None,         小數(shù)位長(zhǎng)度
 
BaseTemporalField(Field)
    input_formats=None          時(shí)間格式化   
 
DateField(BaseTemporalField)    格式:2015-09-01
TimeField(BaseTemporalField)    格式:11:12
DateTimeField(BaseTemporalField)格式:2015-09-01 11:12
 
DurationField(Field)            時(shí)間間隔:%d %H:%M:%S.%f
    ...
 
RegexField(CharField)
    regex,                      自定制正則表達(dá)式
    max_length=None,            最大長(zhǎng)度
    min_length=None,            最小長(zhǎng)度
    error_message=None,         忽略,錯(cuò)誤信息使用 error_messages={'invalid': '...'}
 
EmailField(CharField)      
    ...
 
FileField(Field)
    allow_empty_file=False     是否允許空文件
 
ImageField(FileField)      
    ...
    注:需要PIL模塊,pip3 install Pillow
    以上兩個(gè)字典使用時(shí),需要注意兩點(diǎn):
        - form表單中 enctype="multipart/form-data"
        - view函數(shù)中 obj = MyForm(request.POST, request.FILES)
 
URLField(Field)
    ...
 
 
BooleanField(Field)  
    ...
 
NullBooleanField(BooleanField)
    ...
 
ChoiceField(Field)
    ...
    choices=(),                選項(xiàng),如:choices = ((0,'上海'),(1,'北京'),)
    required=True,             是否必填
    widget=None,               插件,默認(rèn)select插件
    label=None,                Label內(nèi)容
    initial=None,              初始值
    help_text='',              幫助提示
 
 
ModelChoiceField(ChoiceField)
    ...                        django.forms.models.ModelChoiceField
    queryset,                  # 查詢數(shù)據(jù)庫(kù)中的數(shù)據(jù)
    empty_label="---------",   # 默認(rèn)空顯示內(nèi)容
    to_field_name=None,        # HTML中value的值對(duì)應(yīng)的字段
    limit_choices_to=None      # ModelForm中對(duì)queryset二次篩選
     
ModelMultipleChoiceField(ModelChoiceField)
    ...                        django.forms.models.ModelMultipleChoiceField
 
 
     
TypedChoiceField(ChoiceField)
    coerce = lambda val: val   對(duì)選中的值進(jìn)行一次轉(zhuǎn)換
    empty_value= ''            空值的默認(rèn)值
 
MultipleChoiceField(ChoiceField)
    ...
 
TypedMultipleChoiceField(MultipleChoiceField)
    coerce = lambda val: val   對(duì)選中的每一個(gè)值進(jìn)行一次轉(zhuǎn)換
    empty_value= ''            空值的默認(rèn)值
 
ComboField(Field)
    fields=()                  使用多個(gè)驗(yàn)證,如下:即驗(yàn)證最大長(zhǎng)度20,又驗(yàn)證郵箱格式
                               fields.ComboField(fields=[fields.CharField(max_length=20), fields.EmailField(),])
 
MultiValueField(Field)
    PS: 抽象類,子類中可以實(shí)現(xiàn)聚合多個(gè)字典去匹配一個(gè)值,要配合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)     文件選項(xiàng),目錄下文件顯示在頁(yè)面中
    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時(shí)候,可解析為192.0.2.1, PS:protocol必須為both才能啟用
 
SlugField(CharField)           數(shù)字,字母,下劃線,減號(hào)(連字符)
    ...
 
UUIDField(CharField)           uuid類型

五、Form表單的用戶數(shù)據(jù)驗(yàn)證方式:

方式一:內(nèi)置的正則驗(yàn)證:

導(dǎo)入方式:from django.core.validators import RegexValidator
基本格式:validators=[RegexValidator(正則表達(dá)式, "錯(cuò)誤提示"),]

 email = forms.CharField(
        label="郵箱",
        error_messages={
            "required": "郵箱不能為空",
        },
        # 調(diào)用Form組件中的驗(yàn)證器來(lái)校驗(yàn)郵箱
        validators=[RegexValidator(r'^[a-zA-Z0-9_.-]+@[a-zA-Z0-9-]+(\.[a-zA-Z0-9-]+)*\.[a-zA-Z0-9]{2,6}$', "郵箱格式不正確")],
        widget=forms.widgets.TextInput(
            attrs={'class': 'form-control'},  # 給生成的標(biāo)簽添加屬性
        )
    )
方式二、自定義驗(yàn)證
import re
from django.forms import Form
from django.forms import widgets
from django.forms import fields
from django.core.exceptions import ValidationError
 
 
# 自定義驗(yàn)證規(guī)則
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('手機(jī)號(hào)碼格式錯(cuò)誤')
 
 
class PublishForm(Form):
 
    # 使用自定義驗(yàn)證規(guī)則
    phone = fields.CharField(validators=[mobile_validate, ],
                            error_messages={'required': '手機(jī)不能為空'},
                            widget=widgets.TextInput(attrs={'class': "form-control",
                                                          'placeholder': u'手機(jī)號(hào)碼'}))
 
    email = fields.EmailField(required=False,
                            error_messages={'required': u'郵箱不能為空','invalid': u'郵箱格式錯(cuò)誤'},
                            widget=widgets.TextInput(attrs={'class': "form-control", 'placeholder': u'郵箱'}))

首先補(bǔ)充幾個(gè)變量含義,看了源碼了解到的兩個(gè)變量和一個(gè)方法:

  • is_valid():校驗(yàn)用戶
  • cleaned_data --> 用來(lái)存放經(jīng)過(guò)驗(yàn)證數(shù)據(jù)的大字典
  • add_error("字段名", "錯(cuò)誤提示信息")
方式三、局部鉤子驗(yàn)證:
 # 通過(guò)自定義一個(gè)clean_字段名的方法實(shí)現(xiàn)對(duì)Form表單特定字段的校驗(yàn)
    def clean_username(self):
        # 從cleaned_data中取出想要的數(shù)據(jù)
        value = self.cleaned_data.get("username")
        if "金瓶梅" in value:
            # 錯(cuò)誤就拋異常
            raise ValidationError("不符合社會(huì)主義核心價(jià)值觀!")
        else:
            return value
方式四、全局鉤子驗(yàn)證:
# 通過(guò)Form表單的全局鉤子函數(shù)來(lái)驗(yàn)證兩次輸入的密碼是否正確
    # 該clean方法, 在每個(gè)字段都校驗(yàn)通過(guò)之后才調(diào)用執(zhí)行
    def clean(self):
        password = self.cleaned_data.get('password')
        re_password = self.cleaned_data.get('re_password')
        if re_password and password == re_password:
            # 判斷正確就返回校驗(yàn)過(guò)后的數(shù)據(jù)
            return self.cleaned_data
        else:
            # 添加錯(cuò)誤到add_error
            self.add_error('re_password','兩次密碼不一致,請(qǐng)重新輸入')
            # 主動(dòng)拋出異常
            raise ValidationError('兩次密碼不一致,請(qǐng)重新輸入')

六、Form的進(jìn)階騷操作

1、批量添加樣式
通過(guò)重寫(xiě)form類的init方法來(lái)實(shí)現(xiàn)。

class LoginForm(forms.Form):
    username = forms.CharField(
        min_length=8,
        label="用戶名",
        initial="王飛",
        error_messages={
            "required": "不能為空",
            "invalid": "格式錯(cuò)誤",
            "min_length": "用戶名最短8位"
        }
    ...

    def __init__(self, *args, **kwargs):
        super(LoginForm, self).__init__(*args, **kwargs)
        for field in iter(self.fields):
            self.fields[field].widget.attrs.update({
                'class': 'form-control'
            })

2、Django 內(nèi)置的把ORM對(duì)象轉(zhuǎn)換成字典的工具函數(shù)

from django.forms.models import model_to_dict

//book_obj為根據(jù)條件在數(shù)據(jù)庫(kù)中查到的對(duì)象
//obj_dict是book_obj對(duì)象再數(shù)據(jù)庫(kù)中對(duì)應(yīng)的字段和值組成的鍵值對(duì)字典
obj_dict = model_to_dict(book_obj)
//form_obj通過(guò)initial設(shè)置初始化的值,例如,圖書(shū)管理系統(tǒng)中的編輯書(shū)籍功能,
//點(diǎn)擊編輯后跳轉(zhuǎn)到編輯書(shū)籍頁(yè)面,跳轉(zhuǎn)后需要用要編輯的書(shū)籍信息填充頁(yè)面對(duì)應(yīng)信息。
form_obj = forms.BookForm(initial=obj_dict)
    
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書(shū)系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

  • 專業(yè)考題類型管理運(yùn)行工作負(fù)責(zé)人一般作業(yè)考題內(nèi)容選項(xiàng)A選項(xiàng)B選項(xiàng)C選項(xiàng)D選項(xiàng)E選項(xiàng)F正確答案 變電單選GYSZ本規(guī)程...
    小白兔去釣魚(yú)閱讀 10,490評(píng)論 0 13
  • Web框架之Django: (1)簡(jiǎn)介: Django是一個(gè)由Python寫(xiě)成開(kāi)源的重量級(jí)Web應(yīng)用框架,采用MT...
    老肖閱讀 3,160評(píng)論 0 18
  • HTML表單 在HTML中,表單是 ... 之間元素的集合,它們?cè)试S訪問(wèn)者輸入文本、選擇選項(xiàng)、操作對(duì)象等等,然后將...
    蘭山小亭閱讀 3,503評(píng)論 2 14
  • 秋天來(lái)了,樹(shù)葉落了,天氣漸漸變涼了。阿梅的水果店生意越來(lái)越好。阿梅每天都在想象著和老公賺了錢(qián)回老家的幸福生活。白天...
    一筐白菜閱讀 365評(píng)論 0 0
  • 思考與行動(dòng) 1. 在什么事兒上,你“痛心疾首地發(fā)現(xiàn),等我反應(yīng)過(guò)來(lái)的時(shí)候已經(jīng)晚了?” 每個(gè)人都有的,多羅列幾個(gè),然后...
    雅倩1120閱讀 221評(píng)論 2 0

友情鏈接更多精彩內(nèi)容