日韩av黄I国产麻豆传媒I国产91av视频在线观看I日韩一区二区三区在线看I美女国产在线I麻豆视频国产在线观看I成人黄色短片

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 >

Django的Form表单

發(fā)布時(shí)間:2025/7/14 67 豆豆
生活随笔 收集整理的這篇文章主要介紹了 Django的Form表单 小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

Django的Form表單

Django?Form?

Form介紹

Form 表單是在前端向后端提交數(shù)據(jù)最常用的方式,同時(shí)在好多場(chǎng)景下都需要對(duì)用戶的輸入進(jìn)行校驗(yàn)。

以注冊(cè)為例,Form 需要的三件事:

  • 要有一個(gè)注冊(cè)的頁面,頁面里面要有form表單
    生成HTML代碼

  • form表單要能提交數(shù)據(jù)到后端,后端要做有效性校驗(yàn)
    數(shù)據(jù)有效性校驗(yàn)

  • 要把校驗(yàn)的提示信息展示在頁面上
    校驗(yàn)信息返回并展示,保存原來填寫的內(nèi)容

  • 普通方式的注冊(cè)功能

    視圖函數(shù)

    # 注冊(cè) def register(request):error_msg = ""if request.method == "POST":username = request.POST.get("name")pwd = request.POST.get("pwd")# 對(duì)注冊(cè)信息做校驗(yàn)if len(username) < 6:# 用戶長度小于6位error_msg = "用戶名長度不能小于6位"else:# 將用戶名和密碼存到數(shù)據(jù)庫return HttpResponse("注冊(cè)成功")return render(request, "register.html", {"error_msg": error_msg})

    模板

    <!DOCTYPE html> <html lang="en"> <head><meta charset="UTF-8"><title>注冊(cè)頁面</title> </head> <body> <form action="/reg/" method="post">{% csrf_token %}<p>用戶名:<input type="text" name="name"></p><p>密碼:<input type="password" name="pwd"></p><p><input type="submit" value="注冊(cè)"><p style="color: red">{{ error_msg }}</p></p> </form> </body> </html>

    Django 的 Form 組件

    所以,Django 的 Form 組件對(duì)應(yīng)上面所提三件事:

  • 生成頁面可用的HTML標(biāo)簽

  • 對(duì)用戶提交的數(shù)據(jù)進(jìn)行校驗(yàn)

  • 保留上次輸入內(nèi)容

  • 創(chuàng)建 Form 類

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

    要導(dǎo)入的包:

    • from django import forms
      這是 Form 組件的父類,用于創(chuàng)建 Form 類

    • from django.forms import widgets
      用于對(duì)每個(gè)字段指定樣式

    字段與插件

    initial 初始值

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

    class RegForm(forms.Form):username = forms.CharField(min_length=8,label="用戶名",initial="張三"# 設(shè)置默認(rèn)值)pwd = forms.CharField(min_length=6, label="密碼")

    error_messages

    重寫錯(cuò)誤信息。

    class RegForm(forms.Form):name = forms.CharField(# 校驗(yàn)規(guī)則相關(guān)max_length=16,label="用戶名",error_messages={"required": "該字段不能為空","invalid": "格式錯(cuò)誤","man_length": "用戶名最長16位"},# widget控制的是生成HTML代碼相關(guān)的規(guī)則widget=widgets.TextInput(attrs={"class": "form-control"}))

    password

    • render_value=True 提交后輸入框內(nèi)容依然存在
    class RegForm(forms.Form):……pwd = forms.CharField(label="密碼",min_length=6,max_length=10,# render_value=True 提交后輸入框內(nèi)容依然存在widget=widgets.PasswordInput(attrs={"class": "form-control"}, render_value=True),error_messages={"min_length": "密碼不能少于6位!","max_length": "密碼最長10位!","required": "該字段不能為空!"})

    radioSelect

    單radio值為字符串

    class RegForm(forms.Form):……gender = forms.fields.ChoiceField(choices=((1, "男"), (2, "女"), (3, "保密")),label="性別",initial=3,widget=forms.widgets.RadioSelect())

    單選 Select

    class RegForm(forms.Form):...hobby = forms.fields.ChoiceField(choices=((1, "籃球"), (2, "足球"), (3, "雙色球"), ),label="愛好",initial=3,widget=forms.widgets.Select())

    多選 Select

    class RegForm(forms.Form):...hobby = forms.fields.MultipleChoiceField(choices=((1, "籃球"), (2, "足球"), (3, "雙色球"), ),label="愛好",initial=[1, 3],widget=forms.widgets.SelectMultiple())

    單選 checkbox

    class RegForm(forms.Form):...keep = forms.fields.ChoiceField(label="是否記住密碼",initial="checked",widget=forms.widgets.CheckboxInput())

    多選 checkbox

    class RegForm(forms.Form):...hobby = forms.fields.MultipleChoiceField(choices=((1, "籃球"), (2, "足球"), (3, "雙色球"),),label="愛好",initial=[1, 3],widget=forms.widgets.CheckboxSelectMultiple())

    Django Form 所有內(nèi)置字段

    Fieldrequired=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, 最大長度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, 小數(shù)位長度BaseTemporalField(Field)input_formats=None 時(shí)間格式化 DateField(BaseTemporalField) 格式:2015-09-01 TimeField(BaseTemporalField) 格式:11:12 DateTimeField(BaseTemporalField)格式:2015-09-01 11:12DurationField(Field) 時(shí)間間隔:%d %H:%M:%S.%f...RegexField(CharField)regex, 自定制正則表達(dá)式max_length=None, 最大長度min_length=None, 最小長度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.ModelChoiceFieldqueryset, # 查詢數(shù)據(jù)庫中的數(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.ModelMultipleChoiceFieldTypedChoiceField(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)證最大長度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),目錄下文件顯示在頁面中path, 文件夾路徑match=None, 正則匹配recursive=False, 遞歸下面的文件夾allow_files=True, 允許文件allow_folders=False, 允許文件夾required=True,widget=None,label=None,initial=None,help_text=''GenericIPAddressFieldprotocol='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類型Django Form內(nèi)置字段

    生成 HTML 頁面

    方式一:自動(dòng)填寫

    在模板文件 form 中,加入 {{ form_obj.as_p }} 就可以自動(dòng)生成了。

    優(yōu)點(diǎn):方便
    缺點(diǎn):不能添加 CSS 樣式

    <form action="/reg/" method="post" novalidate> {% csrf_token %} {{ form_obj.as_p }} <input type="submit" value="提交"> </form>

    ?


    ?

    方式二:逐個(gè)手寫

    優(yōu)點(diǎn):能夠?yàn)楦鱾€(gè)標(biāo)簽添加 CSS 樣式類,也可以使用 Bootstrap 樣式類等
    缺點(diǎn):代碼量較大

    <link rel="stylesheet" href="/static/bootstrap/css/bootstrap.min.css"> {#方式二:逐個(gè)填充,可以填充樣式#} <div class="container"><div class="row"><div class="col-md-6 col-md-offset-3"><form action="/reg/" method="post" novalidate>{% csrf_token %}<div class="form-group {% if form_obj.name.errors.0 %} has-error {% endif %}">{{ form_obj.name.label }}{{ form_obj.name }}<span class="help-block">{{ form_obj.name.errors.0 }}</span></div><div class="form-group {% if form_obj.pwd.errors.0 %} has-error {% endif %}">{{ form_obj.pwd.label }}{{ form_obj.pwd }}<span class="help-block">{{ form_obj.pwd.errors.0 }}</span></div><div class="form-group {% if form_obj.re_pwd.errors.0 %} has-error {% endif %}">{{ form_obj.re_pwd.label }}{{ form_obj.re_pwd }}<span class="help-block">{{ form_obj.re_pwd.errors.0 }}</span></div><div class="form-group {% if form_obj.email.errors.0 %} has-error {% endif %}">{{ form_obj.email.label }}{{ form_obj.email }}<span class="help-block">{{ form_obj.email.errors.0 }}</span></div><div class="form-group {% if form_obj.mobile.errors.0 %} has-error {% endif %}">{{ form_obj.mobile.label }}{{ form_obj.mobile }}<span class="help-block">{{ form_obj.mobile.errors.0 }}</span></div><div class="form-group {% if form_obj.city.errors.0 %} has-error {% endif %}">{{ form_obj.city.label }}{{ form_obj.city }}<span class="help-block">{{ form_obj.city.errors.0 }}</span></div><div class="form-group"><input type="submit" class="btn btn-default"></div></form></div></div> </div>

    ?

    form2

    ?

    校驗(yàn)

    做校驗(yàn)

    通過函數(shù) is_valid 做校驗(yàn),校驗(yàn)后的各種字段數(shù)據(jù)會(huì)保存在 form_obj.clean_data 中。

    if request.method == "POST":# 更新form_obj的內(nèi)容form_obj = RegForm(request.POST)# form自己可以做校驗(yàn)if form_obj.is_valid():# 1. form_obj.cleaned_data存儲(chǔ)form校驗(yàn)后的內(nèi)容,需要在is-valid函數(shù)后使用del form_obj.cleaned_data["re_pwd"]

    在模板頁面,使用 Form實(shí)例.字段名.errors.0的方式來顯示后端發(fā)來的校驗(yàn)信息。

    <div class="form-group {% if form_obj.name.errors.0 %} has-error {% endif %}">{{ form_obj.name.label }}{{ form_obj.name }}<span class="help-block">{{ form_obj.name.errors.0 }}</span> </div>

    Form 類自帶校驗(yàn)字段

    Form 類設(shè)置的各種字段的值自動(dòng)包含所要校驗(yàn)的內(nèi)容,而校驗(yàn)結(jié)果顯示的信息放在 error_messages 字段中。

    re_pwd = forms.CharField(label="確認(rèn)密碼",min_length=6,max_length=10,widget=widgets.PasswordInput(attrs={"class": "form-control"}, render_value=True),error_messages={"min_length": "密碼不能少于6位!","max_length": "密碼最長10位!","required": "該字段不能為空!"})

    Form 自帶的正則校驗(yàn)

    除了 Form 類中的字段能夠校驗(yàn)外,還需要根據(jù)需求自定義校驗(yàn),其中,正則校驗(yàn)就是一個(gè)比較常用的校驗(yàn)方式, Form 類中自帶正則校驗(yàn)方法。

    from django import forms from django.forms import widgets from django.core.validators import RegexValidator from django.core.exceptions import ValidationErrormobile = forms.CharField(label="手機(jī)",# 自己定制校驗(yàn)規(guī)則validators=[RegexValidator(r'^[0-9]+$',"手機(jī)號(hào)必須是數(shù)字"),RegexValidator(r'^1[3-9][0-9]{9}$', "手機(jī)格式不正確")],widget=widgets.TextInput(attrs={"class": "form-control"}),error_messages={"required": "該字段不能為空"})

    具體字段的自定義校驗(yàn)方法

    在 Form 類中加上 clean_XX 函數(shù),可在其中自定義對(duì) XX 字段的校驗(yàn)。這種方法只能使用此字段。

    在此函數(shù)中,

    • 如果校驗(yàn)出錯(cuò),通過 raise ValidationError("錯(cuò)誤提示信息") 方式拋出提示信息
    • 函數(shù)的最后,即校驗(yàn)成功,返回該字段, return XX
    def clean_name(self):name = self.cleaned_data.get("name")if "中國" in name:raise ValidationError("不要臉") return name

    全局的自定義校驗(yàn)方法

    在 Form 類中,重寫 clean 函數(shù),可以實(shí)現(xiàn)對(duì)多個(gè)字段的自定義校驗(yàn)。

    添加提示信息的方法:

    self.add_error("要添加到哪個(gè)字段的錯(cuò)誤信息", ValidationError("提示的錯(cuò)誤信息"))

    驗(yàn)完成的最后都要將校驗(yàn)字典返回:return self.cleaned_data

    在模板頁面中,依然可以直接用所添加到字段的錯(cuò)誤信息變量:form_obj.name.errors.0

    示例:

    def clean(self):pwd = self.cleaned_data.get("pwd")re_pwd = self.cleaned_data.get("re_pwd")if pwd != re_pwd:self.add_error("re_pwd", ValidationError("兩次密碼不一致!"))# raise ValidationError("兩次密碼不一致")return self.cleaned_data

    Form 與數(shù)據(jù)庫

    有時(shí)候會(huì)遇到這樣的需求:前端頁面中,Form 表單里的數(shù)據(jù)是從數(shù)據(jù)庫中取出來顯示出來,此時(shí)如果向數(shù)據(jù)庫中添加新的數(shù)據(jù),前端頁面不會(huì)顯示出新添加的數(shù)據(jù),只有在重啟后端服務(wù)后才能重新從數(shù)據(jù)庫中取出數(shù)據(jù),便包含了新添加的數(shù)據(jù)。

    解決方法:

    在對(duì) Form 類中要從數(shù)據(jù)庫中取數(shù)據(jù)的字段來說,在該字段進(jìn)行取數(shù)據(jù),所以需要在每次實(shí)例化類的時(shí)候都重新對(duì)該字段進(jìn)行賦值。

    city = forms.ChoiceField( choices=models.City.objects.all().values_list("id", "name"),label="所在城市",initial=1,widget=widgets.Select(attrs={"class": "form-control"}) )# 重寫父類的初始化方法, 每次實(shí)例化類的時(shí)候都調(diào)用 def __init__(self, *args, **kwargs):super().__init__(*args, **kwargs)# 每次實(shí)例化類的時(shí)候都重新給choices賦值,保證更新數(shù)據(jù)庫時(shí)數(shù)據(jù)同步更新self.fields["city"].widget.choices = models.City.objects.all().values_list("id", "name")

    參考:https://www.cnblogs.com/liwenzhou/p/8747872.html

    GitHub地址:https://github.com/protea-ban/oldboy/tree/master/s9day73/ajaxdemo

    ?

    轉(zhuǎn)載于:https://www.cnblogs.com/banshaohuan/p/9531807.html

    總結(jié)

    以上是生活随笔為你收集整理的Django的Form表单的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。