django Widgets

来源:互联网 发布:布吉岛漫画软件 编辑:程序博客网 时间:2024/06/11 12:41

Widgets是HTML输入元素的Django的代表性。该插件处理的HTML的呈现,以及将数据从对应于小窗口的GET / POST字典的提取。

提示
Widgets不应该混淆与表单字段。表单域处理的输入验证逻辑,并直接在模板中使用。Widgets处理网页的原始提交的数据和提取的HTML表单输入元素的渲染。然而,Widgets都需要被分配以形成字段。

Specifying widgets(指定部件)
当你指定一个字段的一种形式时,Django将用默认的部件来显示的数据类型是适当的。要找到这些小部件用于哪些领域上,请查看有关文档 内置领域的类。


但是,如果你想使用一个不同的部件一个字段,你可以使用Widgets上的字段定义参数。例如:


from django import forms
class  CommentForm ( forms . Form ): 
     name  =  forms . CharField () 
     url  =  forms . URLField () 
     comment  =  forms . CharField ( widget = forms.Textarea )
这使用的是较大的注释指明表格textarea的 小部件,而不是默认的文本输入控件。


对于小部件设置的参数

许多部件具有可选额外的参数; 它们可以限定在该领域的插件时被设置。在下面的例子中, 年属性设置为一个 SelectDateWidget:

from  django.forms.fields  import  DateField ,  ChoiceField ,  MultipleChoiceField 
from  django.forms.widgets  import  RadioSelect ,  CheckboxSelectMultiple 
from  django.forms.extras.widgets  import  SelectDateWidget

BIRTH_YEAR_CHOICES  =  ( '1980' ,  '1981' ,  '1982' ) 
FAVORITE_COLORS_CHOICES  =  (( 'blue' ,  'Blue' ),  ( 'green' ,  'Green' ),  ( 'black' ,  'Black' ))


class  SimpleForm ( forms . Form ): 
    birth_year  =  DateField ( widget = SelectDateWidget ( years = BIRTH_YEAR_CHOICES )) 
    favorite_colors  =  forms . MultipleChoiceField ( required = False , 
        widget = CheckboxSelectMultiple ,  choices = FAVORITE_COLORS_CHOICES )
他们接受内置的小工具以获取更多信息部件,及哪些有关的参数。


Widgets inheriting from the Select widget(控件继承于选择控件
控件继承从选择控件处理中选择。他们提供给用户可供选择的列表的选项。不同的部件出现不同的选择; 在选择控件本身使用 <选择> HTML列表的表示,而RadioSelect使用单选按钮。


选择控件默认情况下使用ChoiceField领域。在widget显示的选项是从继承ChoiceField和改变ChoiceField.choices将更新Select.choices。例如:

>>> from django import forms

>>> CHOICES=(('1','First',),('2','Second',))

>>> choice_field=forms.ChoiceField(widget=forms.RadioSelect,choices=CHOICES)

>>> choice_field.choices

[('1', 'First'), ('2', 'Second')]

>>> choice_field.widget.choices

[('1', 'First'), ('2', 'Second')]

>>> choice_field.widget.choices=()

>>> choice_field.choices=(('1','First and only',),)

>>> choice_field.widget.choices

[('1', 'First and only')]

控件提供一个选择的属性可以用它不是基于选择–例如CharField–领域但建议使用choicefield基场当选择模型的固有的不只是代表性的部件。

自定义窗口小部件的实例
当Django呈现一个小部件为HTML,只呈现很小的标记- Django不添加类名称,或其他任何部件的特定属性。这意味着,例如,所有的文本输入小部件将出现在网页上的相同。

有两种方法可以自定义窗口小部件:每个小部件的实例和每个widget类。

造型小部件的实例
如果你想使一个小部件的实例看,从不同的另一种,则需要在指定时间附加属性时,控件对象实例化并分配到一个表单字段(也许添加一些规则,你的CSS文件)。

例如,采取以下简单的形式:

from django import forms

classCommentForm(forms.Form):

     name=forms.CharField()

     url=forms.URLField()

     comment=forms.CharField()

这种形式将包括三个默认的文本输入窗口小部件,使用默认的渲染-没有CSS类,没有额外的属性。这意味着为每个插件的输入框将呈现完全相同的:

>>> f=CommentForm(auto_id=False)

>>> f.as_table()

<tr><th>Name:</th><td><input type="text" name="name" /></td></tr>

<tr><th>Url:</th><td><input type="text" name="url"/></td></tr>

<tr><th>Comment:</th><td><input type="text" name="comment" /></td></tr>

在一个真正的网页,你可能不希望每个小部件看起来是一样的。您可能需要为注释较大的输入元素,你可能会想'名'小工具有一些特殊的CSS类。要做到这一点,您可以使用 Widget.attrs创建窗口小部件时的说法:

class  CommentForm ( forms . Form ): 
    name  =  forms . CharField ( 
                widget = forms . TextInput ( attrs = { 'class' : 'special' })) 
    url  =  forms . URLField () 
    comment  =  forms . CharField ( 
               widget = forms . TextInput ( attrs = { 'size' : '40' }))
那么Django会包含在渲染输出额外的属性:

>>> f=CommentForm(auto_id=False)

>>> f.as_table()

<tr><th>Name:</th><td><input type="text" name="name" class="special"/></td></tr>

<tr><th>Url:</th><td><input type="text" name="url"/></td></tr>

<tr><th>Comment:</th><td><input type="text" name="comment" size="40"/></td></tr>


Styling widget classes(样式控件类)

与窗口小部件,它可以添加媒体(CSS和JavaScript的)和更深入地定制其外观和行为。

简单地说,你需要继承的插件,要么 定义一个类“媒体”作为子类的一个成员,或创建一个属性“媒体”,返回该类的一个实例。

这些方法包括有些高级Python编程和详细的描述形式媒体主题导向。


基础部件类
相应的窗口小部件类的Widget和MultiWidget被所有子类的内置控件,可以作为自定义窗口小部件的基础。

class Widget(attrs=None)
这个抽象类不能被渲染,但提供了基本的属性 ATTRS。您也可以实现或重写 render()方法自定义窗口小部件的方法。

ATTRS一个包含HTML的字典属性要在渲染窗口小部件设置。

>>> name=forms.TextInput(attrs={'size':10,'title':'Your name',})

>>> name.render('name','A name')

u'<input title="Your name" type="text" name="name" value="A name" size="10" />'


render(name, value, attrs=None)

返回HTML小部件,作为一个Unicode字符串。这种方法必须由子类来实现,否则NotImplementedError将提高。
“价值”给予不保证是有效的输入,因此子类实现应该编程防守。

value_from_datadict(self, data, files, name)
由于数据字典和这个小部件的名称,返回该控件的值。返回无如果不提供一个值。


class MultiWidget(widgets, attrs=None)

这是由多个部件的部件。 MultiWidget工程携手与 MultiValueField。




MultiWidget有一个必需的参数:




部件
包含所需要的部件一个可迭代。




和一个所需的方法:




解压缩(值)
此方法需要从外地一个“压缩”值,并返回的“解压缩”值的列表。输入值可以假定有效的,但不一定非空。




这种方法必须实现的子类,因为该值可能为空,执行必须是防御性的。




后面的“减压”的理由是,既要“分裂”的表单域的总价值为每个插件的值。




这方面的一个例子是如何SplitDateTimeWidget把一个 日期时间值转换成日期和时间分割成两个独立的值的列表:




类 SplitDateTimeWidget (MultiWidget ):




    #...




    def  decompress ( self ,  value ): 
        if  value : 
            return  [ value . date (),  value . time () . replace ( microsecond = 0 )] 
        return  [ None ,  None ]
提示
需要注意的是MultiValueField有一个互补的方法压缩() 与相对的责任-所有成员字段的值,洗净合并成一个。
这可能是有用的,以覆盖其他的方法包括:




渲染(名字,值,ATTRS =无)
自变量的值是从子类不同的方式处理这个方法,小工具,因为它必须弄清楚如何在多个小部件的显示拆分的单个值。




该值呈现可以是以下两种情况之一时使用的参数:




à 列表。
单一值(如字符串)这是一个的“压缩”代表名单价值观。
如果值是一个列表,输出render()方法将呈现子控件的串联。如果值不是一个列表,它会先通过该方法加工的 解压缩()来创建列表,然后渲染。




当渲染()执行它的HTML呈现,列表中的每个值被呈现与相应的插件-第一个值是在所述第一小部件呈现时,所述第二值是在所述第二部件等呈现




不像在单值部件,方法使() 不必在子类中实现。




format_output(rendered_widgets)
由于呈现小部件的列表(字符串),返回一个Unicode字符串,它表示的HTML一大堆。




此挂钩可以让你格式化控件的HTML的设计,任何方式你喜欢。




下面是一个例子部件的子类MultiWidget显示日期的日,月和年在不同的选择框。这个小工具是为了与一个使用的DateField而不是MultiValueField,因此我们实施 value_from_datadict() :


from datetime import date

from django.forms import widgets


class DateSelectorWidget(widgets.MultiWidget):

     def__init__(self,attrs=None):

          # create choices for days, months, years

          # example below, the rest snipped for brevity.

          years=[(year,year)foryearin(2011,2012,2013)]

  _widgets  = (

widgets.Select(attrs=attrs,choices=days),

widgets.Select(attrs=attrs,choices=months),

widgets.Select(attrs=attrs,choices=years),

)

super(DateSelectorWidget,self).__init__(_widgets,attrs)


    def  decompress(self,value):

 if value:

return[value.day,value.month,value.year]

 return[None,None,None]

def  format_output(self,rendered_widgets):
       return u''.join(rendered_widgets)

  def  value_from_datadict ( self ,  data ,  files ,  name ): 
        datelist  =  [ 
            widget . value_from_datadict ( data ,  files ,  name  +  '_ %s '  %  i ) 
            for  i ,  widget  in  enumerate ( self . widgets )] 
        try : 
            D  =  date ( day = int ( datelist [ 0 ]),  month = int ( datelist [ 1 ]), 
                    year = int ( datelist [ 2 ])) 
        except  ValueError : 
            return  '' 
        else : 
            return  str ( D )
构造函数创建几个选择中的元组部件。在 超类使用这个元组来设置控件。




该format_output()方法是相当香草这里(其实,这是一样的什么被实现为默认 MultiWidget),但这个想法是,你可以添加你应该想的部件之间的自定义HTML。




所需的方法解压缩()打破了 datetime.date值到日,月和年对应每个插件的值。注意:该方法如何处理其中的情况下的值是 无。




的默认实现value_from_datadict()返回对应于每一个值的列表控件。这是适当的使用时MultiWidget与MultiValueField,但因为我们想用这个小工具了的DateField 这需要一个单独的值,我们重写此方法的所有subwidgets的数据组合成一个datetime.date。该方法从提取数据的POST字典和结构,并验证日期。如果它是有效的,我们返回字符串,否则,我们返回,这将导致一个空字符串form.is_valid返回假。




内置部件
Django提供各种基本HTML小的表示形式,再加上一些常用的窗口小部件的基团中的django.forms.widgets模块,包括文本的输入,各个复选框和选择器,文件上传和多值输入的处理。




小工具来处理文本输入
这些部件使用的HTML元素的输入和文本区域。




文本输入
类文本输入
文字输入:<输入 类型=“文本” ...>




PasswordInput
类PasswordInput 
密码输入:<输入 类型='密码' ...>




带有一个可选的参数:




render_value 
确定部件是否有填充时,重新显示表单验证错误后(默认为一个值假)。




改变在Django 1.3:为默认值 render_value从改变真为假
HiddenInput
类HiddenInput 
隐藏的输入:<输入 类型=“隐藏” ...>




需要注意的是,也存在着MultipleHiddenInput小部件,封装了一组隐藏的input元素。




DateInput
类DateInput 
日期输入一个简单的文本框:<输入 类型=“文本” ...>




带有一个可选的参数:




格式
在此字段的初始值将被显示的格式。




如果没有格式提供参数,默认格式是找到的第一个格式DATE_INPUT_FORMATS和尊重 格式的本地化。




DateTimeInput
类DateTimeInput 
日期/时间输入一个简单的文本框:<输入 类型=“文本” ...>




带有一个可选的参数:




格式
在此字段的初始值将被显示的格式。




如果没有格式提供参数,默认格式是找到的第一个格式DATETIME_INPUT_FORMATS和尊重 格式的本地化。




TimeInput
类TimeInput 
一次输入一个简单的文本框:<输入 类型=“文本” ...>




带有一个可选的参数:




格式
在此字段的初始值将被显示的格式。




如果没有格式提供参数,默认格式是找到的第一个格式TIME_INPUT_FORMATS和尊重 格式的本地化。




textarea的
类文本区域
文本区:<文本域> ... </ textarea>的




选择和复选框控件
CheckboxInput
类CheckboxInput 
复选框:<输入 类型=“复选框” ...>




带有一个可选的参数:




check_test 
可调用,是以CheckBoxInput的值,并返回 真如果复选框应检查该值。




选择
类选择
选择小工具:<选择> <选项 ...> ... </ SELECT>




选择
此属性是可选字段时没有 选择属性。如果是的话,它会覆盖任何东西,你在这里设置时,该属性被更新的字段。




NullBooleanSelect
类NullBooleanSelect 
与选择“未知”,“是”和“否”选择窗口小部件


选择多
类选择多
类似的选择,但允许多选: <选择 多个='多'> ... </ SELECT>

RadioSelect
类RadioSelect 
类似的选择,但是呈现为单选按钮在列表 <LI>标签:



<UL>

<li><input type='radio' ...></li>

...

</UL>

新在Django 1.4: 请参阅发行说明
为了更精确地控制生成的标记,你可以遍历模板中的单选按钮。Assuming a form myform with a field beatles that uses a RadioSelect as its widget:


{%for radioin myform.beatles%}

<div class="myradio">

{{radio}}

</div>

{%endfor%}

这将产生以下HTML:
<div  class= "myradio" > 
    <label><input  type= "radio"  name= "beatles"  value= "john"  /> John </label> 
</div> 
<div  class= "myradio" > 
    <label><input  type= "radio"  name= "beatles"  value= "paul"  /> Paul </label> 
</div> 
<div  class= "myradio" > 
    <label><input  type= "radio"  name= "beatles"  value= "george"  /> George </label> 
</div> 
<div  class= "myradio" > 
    <label><input  type= "radio"  name= "beatles"  value= "ringo"  /> Ringo </label> 
</div>
这包括了<标签>标签。为了获得更精细的,您可以使用每个单选按钮的标签和choice_label属性。例如,该模板...




{%  for  radio  in  myform.beatles  %} 
    <label> 
        {{  radio.choice_label  }} 
        <span  class= "radio" > {{  radio.tag  }} </span> 
    </label> 
{%  endfor  %}
......将导致下面的HTML:


<label>
    John

    <spanclass="radio"><inputtype="radio"name="beatles"value="john"/></span>

</label>

<label>

     Paul

    <spanclass="radio"><inputtype="radio"name="beatles"value="paul"/></span>

</label>

<label>

    George

    <spanclass="radio"><inputtype="radio"name="beatles"value="george"/></span>

</label>

<label>

    Ringo

    <spanclass="radio"><inputtype="radio"name="beatles"value="ringo"/></span>

</label>

如果您决定不遍历所有的单选按钮-例如,如果你的模板只是包含 {{ myform.beatles }} -他们将要输出的<UL>与<li>标签,如上。




CheckboxSelectMultiple
Class CheckboxSelectMultiple 
类似的选择多,而且呈现为检查按钮的列表:




<UL>
  <li><input type='checkbox' ...></li>
  ......

</ UL>


文件上传控件

FileInput
 Class FileInput 
    File upload input: <inputtype='file'...>




ClearableFileInput
Class ClearableFileInput 
新在Django 1.3: 请参阅发行说明
文件上传输入:<输入 类型='文件' ...> ,用一个附加的复选框输入来清除该字段的值,如果不需要的字段,并具有初始数据。




复合材料部件
MultipleHiddenInput
类MultipleHiddenInput 
多<输入 类型=“隐藏” ...>小部件。




能处理多种隐藏的小部件有值列表字段的Widget。




选择
此属性是可选字段时没有 选择属性。如果是的话,它会覆盖任何东西,你在这里设置时,该属性被更新的字段。




SplitDateTimeWidget
类SplitDateTimeWidget ¶
包装器(使用MultiWidget)左右两个小部件:DateInput 的日期,并TimeInput的时间。




SplitDateTimeWidget有两个可选属性:




DATE_FORMAT 
类似DateInput.format




TIME_FORMAT 
类似TimeInput.format




SplitHiddenDateTimeWidget
类SplitHiddenDateTimeWidget 
类似SplitDateTimeWidget,但使用HiddenInput两个日期和时间。




SelectDateWidget
类SelectDateWidget 
包装器3 选择小部件:分别用于月,日,年。需要注意的是这个小部件生活在从标准部件的单独文件。




带有一个可选的参数:





多年的可选列表/元组中的“年”选择框来使用。默认值是包含当年和未来10年清单。




0 0
原创粉丝点击