Django中的ModelForm與Form


django表單系統中,所有的表單類都作為django.forms.Form的子類創建,包括ModelForm.
關於django中的表單系統有兩種:

  • 基於django.forms.Form
  • 基於django.forms.ModelForm

表單API

form.is_bound()

表單有兩種狀態:綁定和未綁定,使用form.is_bound()來判斷.

form.is_valid()

驗證表單數據是否合法,返回True或者False

form.errors

表單的錯誤字典

Form.has_error(field,code=None)

該方法返回一個布爾值,指定一個字段是否具有與特定錯誤的錯誤code。如果code是None,它將返回True

form.initial

提供初始值,在表單未綁定的情況下,為表單字段設置初始值.
作為一個有參數的表單, 在實例化一個表單時可以通過指定initial字段來指定表單中數據的初始值. 以這種方式提供的初始值將覆蓋表單字段的初始值和附加模型實例的值。

>>> article = Article.objects.get(pk=1)
>>> article.headline
'My headline'
>>> form = ArticleForm(initial={'headline': 'Initial headline'}, instance=article)
>>> form['headline'].value()
'Initial headline'

這些值僅對未綁定的表單顯示

>>> f = ContactForm(initial={'subject': 'Hi there!'})

form.has_changed()

檢查表單數據是否發生變化

form.clened_data

在每個字段Form類不僅負責驗證數據,也為“清潔” -它歸到一個一致的格式。這是一個很好的功能,因為它允許以各種方式輸入特定字段的數據,總是導致一致的輸出。

例如,DateField標准化輸入到Python datetime.date對象。不管你是否傳遞一個字符串中的格式'1994-07-15',一個datetime.date對象,或者一些其他的格式,DateField將始終將它規范化為一個datetime.date,只要它是有效的對象。

一旦你創建一個Form實例與一組數據並驗證它,你可以通過它訪問干凈的數據cleaned_data屬性:

>>> data = {'subject': 'hello',
...         'message': 'Hi there',
...         'sender': 'foo@example.com',
...         'cc_myself': True}
>>> f = ContactForm(data)
>>> f.is_valid()
True
>>> f.cleaned_data
{'cc_myself': True, 'message': 'Hi there', 'sender': 'foo@example.com', 'subject': 'hello'}

請注意,任何基於文本的領域-如CharField或EmailField-始終清潔輸入Unicode字符串。

如果您的數據並沒有被驗證通過,該cleaned_data詞典只包含有效的字段:

>>> data = {'subject': '',
...         'message': 'Hi there',
...         'sender': 'invalid email address',
...         'cc_myself': True}
>>> f = ContactForm(data)
>>> f.is_valid()
False
>>> f.cleaned_data
{'cc_myself': True, 'message': 'Hi there'}

當Form有效時,cleaned_data將包括一個鍵和值 的所有其字段,即使數據沒有包括一些可選字段的值。在這個例子中,數據字典不包括用於一個值 nick_name字段,但是cleaned_data包含它,用空值:

>>> from django import forms
>>> class OptionalPersonForm(forms.Form):
...     first_name = forms.CharField()
...     last_name = forms.CharField()
...     nick_name = forms.CharField(required=False)
>>> data = {'first_name': 'John', 'last_name': 'Lennon'}
>>> f = OptionalPersonForm(data)
>>> f.is_valid()
True
>>> f.cleaned_data
{'nick_name': '', 'first_name': 'John', 'last_name': 'Lennon'}

在本例中,cleaned_data為值nick_name設置為空字符串,因為nick_name是CharField和CharField請客空值作為空字符串。每個字段類型都知道它的“空白”的值是多少-例如,對DateField,這是None不是空字符串。

form.as_p()

將表單渲染成<p>標簽:

>>> f = ContactForm()
>>> f.as_p()
'<p><label for="id_subject">Subject:</label> <input id="id_subject" type="text" name="subject" maxlength="100" required /></p>\n<p><label for="id_message">Message:</label> <input type="text" name="message" id="id_message" required /></p>\n<p><label for="id_sender">Sender:</label> <input type="text" name="sender" id="id_sender" required /></p>\n<p><label for="id_cc_myself">Cc myself:</label> <input type="checkbox" name="cc_myself" id="id_cc_myself" /></p>'
>>> print(f.as_p())
<p><label for="id_subject">Subject:</label> <input id="id_subject" type="text" name="subject" maxlength="100" required /></p>
<p><label for="id_message">Message:</label> <input type="text" name="message" id="id_message" required /></p>
<p><label for="id_sender">Sender:</label> <input type="email" name="sender" id="id_sender" required /></p>
<p><label for="id_cc_myself">Cc myself:</label> <input type="checkbox" name="cc_myself" id="id_cc_myself" /></p>

form.as_ul()

將表單渲染成形式為一系列的<li>標記,每個<li>含有一個字段。它不包括<ul></ul>,這樣就可以在指定的任何HTML屬性<ul>的靈活性:

>>> f = ContactForm()
>>> f.as_ul()
'<li><label for="id_subject">Subject:</label> <input id="id_subject" type="text" name="subject" maxlength="100" required /></li>\n<li><label for="id_message">Message:</label> <input type="text" name="message" id="id_message" required /></li>\n<li><label for="id_sender">Sender:</label> <input type="email" name="sender" id="id_sender" required /></li>\n<li><label for="id_cc_myself">Cc myself:</label> <input type="checkbox" name="cc_myself" id="id_cc_myself" /></li>'
>>> print(f.as_ul())
<li><label for="id_subject">Subject:</label> <input id="id_subject" type="text" name="subject" maxlength="100" required /></li>
<li><label for="id_message">Message:</label> <input type="text" name="message" id="id_message" required /></li>
<li><label for="id_sender">Sender:</label> <input type="email" name="sender" id="id_sender" required /></li>
<li><label for="id_cc_myself">Cc myself:</label> <input type="checkbox" name="cc_myself" id="id_cc_myself" /></li>

form.as_table()

跟上面的as_ul()相同,需要自己添加table標簽

>>> f = ContactForm()
>>> f.as_ul()
'<li><label for="id_subject">Subject:</label> <input id="id_subject" type="text" name="subject" maxlength="100" required /></li>\n<li><label for="id_message">Message:</label> <input type="text" name="message" id="id_message" required /></li>\n<li><label for="id_sender">Sender:</label> <input type="email" name="sender" id="id_sender" required /></li>\n<li><label for="id_cc_myself">Cc myself:</label> <input type="checkbox" name="cc_myself" id="id_cc_myself" /></li>'
>>> print(f.as_ul())
<li><label for="id_subject">Subject:</label> <input id="id_subject" type="text" name="subject" maxlength="100" required /></li>
<li><label for="id_message">Message:</label> <input type="text" name="message" id="id_message" required /></li>
<li><label for="id_sender">Sender:</label> <input type="email" name="sender" id="id_sender" required /></li>
<li><label for="id_cc_myself">Cc myself:</label> <input type="checkbox" name="cc_myself" id="id_cc_myself" /></li>

設置表單必填行與錯誤行的樣式

關鍵字:

  • Form.error_css_class
  • Form.required_css_class

用法:

from django import forms
class ContactForm(Form):
    error_css_class = 'error'      #錯誤行樣式在HTML中表示class='error'
    required_css_class = 'required' #必填樣式在Html中表示clss=‘required’

然后在css文件中定義error與required類就行了.

配置表單元素的HTML id屬性,<label>標簽

from.auto_id

>>> f = ContactForm(auto_id=False) #這樣在html中表單不包含< label >標簽
>>> f = ContactForm(auto_id=True) #在html中表單<label>標簽將為每個表單的id
>>> f = ContactForm(auto_id='id_for_%s') #在html中表單<label>標簽為id_for_字段id

From.prefix

可以為Django表單添加一個命名空間

>>> mother = PersonForm(prefix='mother')
>>> father = PersonForm(prefix='father')

Field.required

表示該字段為必填 缺省為必填項,如需要指定不為必須

>>> f=forms.CharField(required=True)

Field.label

表示友好的label,表單在頁面顯示時用到它

name=from.CharField(label="Your name")

Field.help_text

顯示字段描述文本

Field.error_message

覆蓋默認的錯誤信息

name = forms.CharField(error_messages={'required':'Please enter your name'}) #覆蓋required的默認錯誤信息

widget

負責渲染網頁上的HTML表單

widget.attrs

設置weidget實例樣式

class CommentForm(forms.Form):
    name=forms.CharField(widget=forms.TextInput(attrs={'class':'special'}))
    comment = forms.CharField(widget= forms.TextInput(attrs={'size':'40'}))

以上自定義了name字段的輸入樣式為類 special,comment更改size的大小為40。

內建的widget

TextInput
NumberInput
EmailInput
URLInput
PasswprdInput
HiddenInput
DateInput 日期
DateTimeInput 日期/時間
TimeInput 時間
Textarea
CheckboxInput
Select
NullBooleanSelect 渲染成 unknown,yes,no三個選項
SelectMultiple
RadioSelect
CheckboxSelectMultiple 復選框列表
FileInput 文件上傳
SelectDateWidget

ModelForm表單

from django.forms import ModelForm
from myapp.models import Article
class ArticleForm(ModelForm):
    class Meta:
        model = Article  #表單對應的model
        fields = ['pub_date', 'headline', 'content', 'reporter']  #表單中顯示的字段,對應models.py中對應的字段

這里需要注意一下:model=article,指定表單對應的model
使用方式:

>>>form =  ArticleForm()
>>>article = Article.objects.get(pk=1)
>>>form = ArticleForm(instance = article)  #賦值instance可以使form表單是可以接受對象的數據

這里需要注意的:instance=article,賦值實例instance,可以使form表單可以接受對象類型的數據

instance 屬性,表示與它綁定的模型實例

save()方法

每一個ModelForm都有一個save()方法,這個方法可以根據綁定的form表單創建並且保存一個數據庫對象,ModelForm的子類可以接受一個model的子類作為instance的參數,如果存在那么save()方法會更新這個實例,否則會創建一個新的實例

def table_change(request,table_db_name,obj_id):
    if table_db_name in admin.enabled_admins:
    obj = admin.enabled_admins[table_db_name].model.objects.get(id=obj_id)
    field = [field.name for field in admin.enabled_admins[table_db_name._meta.fields]
    if request.method == 'POST':
        form = model_form(request.POST,instance=obj)
        if form.is_valid():
            form.save()
    else:
        form = model_form(instance=obj)
    return render(request,"king_admin/table_change.html",{'form':form})

save(commit=False)

save()方法接受一個commit的參數,其值為True或者False。默認為True。
如果你聲明 save(commit=False),那么它就會返回一個還未保存至數據庫的對象,這樣的話 你可以用這個對象添加一些額外的數據,然后在用save()保存到數據庫.

def edit(request,sid):
    edit_obj = get_object_or_404(PointRule,id=sid)
    if request.method == 'POST':
        form = PointRuleForm(request.POST.copy(),instance=edit_obj)
        if form.is_valid():
            point = form.save(commit=False)
            point.update_user = request.user  #在form.save(commit=False時,添加一些表單中未有的數據)
            point.save()
            return redirect('point:index')
        else:
            messages.error(request, u'數據驗證錯誤')
    else:
        form = PointRuleForm(instance=edit_obj)
        return render(request,'point/edit.html',locals())

save_m2m()方法

在save(commit=False)的時候,如果你的model中含有many-to-many的數據模型,那么你將無法使用save()方法去保存數據,只能使用save_m2m()方法來保存.

在為聲明save(commit=False),則不用如此保存,用save()就好了...

field字段使用

選擇model中所有字段為表單中的字段

__all__

例子:

from django.forms import ModelForm
class AuthorForm(ModelForm)
    class Meta:
         model = Author
         fields='__all__'

剔除指定字段的所有數據 exclude

class PartialAuhorForm(ModelForm):
    class Meta:
        model = Author
        exclude = ['title'] #添加Author model中除了titile字段的所有字段至PartialAuhorForm表單

覆蓋字段的默認值

form django.forms import ModelForm, Textarea
form myapp.models import Author
    class AuthorForm(ModelForm):
        class Meta:
            model=Author
            fields=('name','title','birth_date')
            widgets={'name':Textarea(attrs={'cols':80,'rows':20})}
from django.utils.translation import ugettext_lazy as _
 class AuthorForm(ModelForm):
      class Meta:
          model=Author
          fields=('name','title','birth_date')
          labels = { 'name':_('Writer'), }
          help_texts = {'name':_('some useful help text.'),}
          error_messages={ 'name':{'max_length':_("this writer name is too long")} }


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM