日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

Django学习笔记之——Forms

發(fā)布時間:2024/4/14 编程问答 28 豆豆
生活随笔 收集整理的這篇文章主要介紹了 Django学习笔记之——Forms 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

2019獨角獸企業(yè)重金招聘Python工程師標(biāo)準(zhǔn)>>>


前面學(xué)習(xí)的都只是如何顯示數(shù)據(jù),但一直沒有關(guān)于如何響應(yīng)用戶提交的數(shù)據(jù)。
表單,是在web中,用戶與服務(wù)器交互的重要途徑。

import django.forms
form django import forms
之間的區(qū)別是什么?

form在Django中扮演的角色有:
*顯示form
*驗證用戶提交的數(shù)據(jù)

form的定義
~~~~~~~~~~

form的定義與model的定義非常相似:
____________________________________________
from django import forms
class BookForm(forms.Form):
??? isbn= forms.CharField(max_length=200)
??? title = forms.CharField(max_length=200)
--------------------------------------------
定義了一個BookForm表單,表單里有isbn與title兩項。

BookForm可以生成html表單文本,如下:
____________________________
book_form = BookForm()
html = book_form.as_table()
print(html)
----------------------------
執(zhí)行打印出的結(jié)果是:
<tr><th><label for="id_isbn">Isbn:</label></th><td><input id="id_isbn" maxlength="50" name="isbn" type="text" /></td></tr>
<tr><th><label for="id_title">Title:</label></th><td><input id="id_title" maxlength="200" name="title" type="text" /></td></tr>

可以看出,打印出來的文本沒有包含<form>與<input type="submit">,這些需要我們
在模板中指定。Form只負(fù)責(zé)isbn與title的輸入,而不關(guān)心form的動作與提交方式。
所以,我們最好用模板的方法先定義好一個模板,如book-form.html:
_______________________________
<form action="." method="get">
??? {{book_form}}
??? <br>
??? <input type="submit">
</form>
-------------------------------
在views.py中用render_to_response()生成HttpResponse:
____________________________________________________
def book_view(request):
??? book_form = BookForm()
??? response = render_to_response('book-form.html',
??????????? {'book_form':book_form.as_table()})
----------------------------------------------------
返回的頁面源碼:
<form action="." method="get">
??? <tr><th><label for="id_isbn">Isbn:</label></th><td><input id="id_isbn" maxlength="50" name="isbn" type="text" /></td></tr>
<tr><th><label for="id_title">Title:</label></th><td><input id="id_title" maxlength="200" name="title" type="text" /></td></tr>
??? <br>
??? <input type="submit">
</form>

Form除了as_table()方法,還有as_ul()與as_p()方法,默認(rèn)是as_table()方法。

Form是在 django/forms/forms.py 定義的。
打開forms.py文件,可以了解到,Form繼承于BaseForm。
BaseForm的定義大致如下:
___________________________________________________________________________
class BaseForm(object):
??? def __init__(self, data=None, files=None, auto_id='id_%s', prefix=None,
??????????? initial=None, label_suffix=None):
??????? ...
??? def as_table(self):
??????? ...
??? def as_ul(self):
??????? ...
??? def as_p(self):
??????? ...
??? def __str__(self):
??????? return self.as_table()

class Form(BaseForm):
??? ...
---------------------------------------------------------------------------
auto_id為<input id="id_xxx">,控件的自動id格式。為''或None表示不需要id。
label_suffix為lable名稱的后綴,默認(rèn)為":",可以改。比如:label_suffix="="
prefix為name的前綴,如果設(shè)置了prefix="aaa",那么<input name="aaa-xxx">
initial為初始值字典。

上面BookForm中只用到了一種域:CharField。除此之外還有很多種。
Fields定義在django/forms/fields.py文件里。

打開fields.py文件,可以看到除CharField外還有更多的Field供選擇:
Field
|--CharField
|? |--RegexField
|? |--EmailField
|? |--URLField
|? |--IPAddressField
|? |--GenericIPAddressField
|? `--SlugField
|--IntegerField
|? |--FloatField
|? `--DecimalField
|--BaseTomporalField
|? |--DateField
|? |--TimeField
|? `--DateTimeField
|--FileField??????? #file選擇文件
|? `--ImageField
|--BooleanField???? #checkbox
|? `--NullBooleanField? #select:Unknow,Yes,No
|--ChoiceField????? #select
|? |--TypedChoiceField
|? |--FilePathField
|? `--MultipleChoiceField
|???? `--TypedMultipleChoiceField
|--ComboField
`--MultiValueField
?? `--SplitDateTimeField

每種Field有個默認(rèn)的Widget。
__________________________________
class Field(object):
??? widget = TextInput
??? ...
class EmailField(CharField):
??? widget = EmailInput
??? ...
class FileField(Field):
??? widget = ClearableFileInput
??? ...
----------------------------------
Widget告訴Field生成哪種web控件。

我們也可以為Field指定Widget。
比如登陸表單:
_____________________________________________________________
class LoginForm(forms.Form):
??? #email = forms.EmailField()
??? email = forms.CharField(widget=widgets.EmailInput())
??? password = forms.CharField(widget=widgets.PasswordInput())
-------------------------------------------------------------
password這個域不能用明文顯示,所以更改了widget。

所有的Widget都定義在django/forms/widgets.py中。
有如下控件:
'Media', 'MediaDefiningClass', 'Widget', 'TextInput',
'EmailInput', 'URLInput', 'NumberInput', 'PasswordInput',
'HiddenInput', 'MultipleHiddenInput', 'ClearableFileInput',
'FileInput', 'DateInput', 'DateTimeInput', 'TimeInput', 'Textarea',
'CheckboxInput', 'SplitDateTimeWidget',
'Select', 'NullBooleanSelect', 'SelectMultiple', 'RadioSelect',
'CheckboxSelectMultiple', 'MultiWidget',


基于模型的表單
~~~~~~~~~~~~~~
根據(jù)模型的定義來自動定義表單。如下:
______________________________________
from django import forms
from models import Book
class BookModelForm(froms.ModelForm):
??? class Meta:
??????? model = Book
--------------------------------------
而Book的定義在models.py里:
____________________________________________
class Book(models.Model):
??? isbn = models.CharField(max_length=50)
??? title = models.CharField(max_length=200)
??? author = models.ForeignKey('Author')

??? def __unicode__(self):
??????? return self.title
--------------------------------------------
這樣以來,BookModelForm也有了與Book對應(yīng)的isbn,title,author。

保存ModelForm
~~~~~~~~~~~~~
ModelForm與一般的Form的重要區(qū)別是,ModelForm具有save()功能。能將表單里的數(shù)據(jù)
加入到數(shù)據(jù)庫,并返回一個Model對象。
為了演示方便,我就不采用模板了。同樣是引用上面BookModelForm與Book:
_________________________________________________________________
def add_book_view(request):
??? book_form = forms.BookModelForm(request.GET)
??? try:
??????? book_model = book_form.save()
??????? content = '<p>Add ' + book_model.title + ' success!</p>'
??? except:
??????? content =? '<form action="." method="get">'
??????? content += book_form.as_p()
??????? content += '<input type="submit"></form>'
??? return HttpResponse(content)
-----------------------------------------------------------------
并將add_book_view視圖的url指定為r'^add-book/'。

第一次訪問/add-book/時,由于GET中沒有參數(shù),所以在book_form.save()就會拋出異
常。在except中返回個表單給用戶。用戶填好后提交。這次再處理時,GET里就有數(shù)據(jù)
了,所以book_form.save()正常,最后輸出success消息。

有時,我們在save()時僅僅是想驗證一下用戶的輸入,并不打算提交到數(shù)據(jù)為。
這里,只要save(commit=False)即可。
如此,在save(commit=False)時返回了book模型的對象。我們可以繼而對其進一步修改
,再保存到數(shù)據(jù)庫。
_____________________________________________________
??????? #book_model = book_form.save()
??????? book_model = book_form.save(commit=False)
??????? book_model.title = 'Balabala'
??????? book_model.save()
-----------------------------------------------------
第一行只是驗證一下用戶的輸出是不是符合要求。然后對模型對象進行修改,最后才保
存到數(shù)據(jù)庫去。就這樣,在中間改了title,然后再保存到了數(shù)據(jù)庫。

ModelForm顯示個別域
~~~~~~~~~~~~~~~~~~~
ModelForm默認(rèn)情況下,與Model是一致的。但是很多時候,并不是模型中所有的域都要
讓用戶填的。我們可以選擇性地選擇或排除個別域。
這里就要用到Meta的exclude或fields。exclude表示排除什么域,而fields表示需要顯
示哪些域。二者不能同時使用。
_________________________________________________
class BookModelForm(forms.ModelForm):
??? class Meta:
??????? model = Book
??????? exclude = ('author') #表示不顯示author域
-------------------------------------------------
_________________________________________________
class BookModelForm(forms.ModelForm):
??? class Meta:
??????? model = Book
??????? fields = ('title', 'isbn')
??????? #表示只顯示title與isbn域
-------------------------------------------------

重寫ModelForm中的域
~~~~~~~~~~~~~~~~~~~
_________________________________________
class BookModelForm(forms.ModelForm):
??? isbn = forms.CharField(max_length=13)
??? class Meta:
??????? model = Book
-----------------------------------------
將Book中指定的CharField(max_length=50),改成了13。

新增ModelForm中的域
~~~~~~~~~~~~~~~~~~~
______________________________________
class BookModelForm(forms.ModelForm):
??? review = forms.CharField()
??? class Meta:
??????? model = Book
--------------------------------------
這樣以來,BookModelForm不僅只有Book中的域,還有review。

表單的驗證
~~~~~~~~~~
Form的is_valid()文件可以用來驗證數(shù)據(jù)是否合法。
如果數(shù)據(jù)合法,Form對象則會有cleaned_data屬性。如果不合法,則是errors。
__________________________________________________________________
def add_author_view(request):
??? content = None
??? if request.GET: # 檢查GET是否有表單數(shù)據(jù)
??????? author_form = forms.AuthorModelForm(request.GET)
??????? if author_form.is_valid():? # 檢查數(shù)據(jù)是否合法
??????????? print(author_form.cleaned_data)
??????????? try:
??????????????? author_form.save()
??????????????? content = '<p>Success</p>'
??????????? except:
??????????????? content = '<p>Something wrong while saving.</p>'
??????? else:
??????????? content = str(author_form.errors) # 用errors返回錯誤信息
??? else:
??????? content =? '<form action=".">'
??????? content += forms.AuthorModelForm().as_p()
??????? content += '<input type="submit"></form>'
??? return HttpResponse(content)
------------------------------------------------------------------
上面用到了author_form.is_valid()進行數(shù)據(jù)合法性驗證。
如果成功,則會有author_form.cleaned_data,如果失敗會有author_form.errors。
這兩則只會存在一個,不會同時存在。

轉(zhuǎn)載于:https://my.oschina.net/hevakelcj/blog/383185

超強干貨來襲 云風(fēng)專訪:近40年碼齡,通宵達旦的技術(shù)人生

總結(jié)

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

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