class ChoiceInput(SubWidget): """ An object used by ChoiceFieldRenderer that represents a single <input type='$input_type'>. """ input_type = None # Subclasses must define this def __init__(self, name, value, attrs, choice, index): self.name = name self.value = value self.attrs = attrs self.choice_value = force_text(choice[0]) self.choice_label = force_text(choice[1]) self.index = index if 'id' in self.attrs: self.attrs['id'] += "_%d" % self.index def __str__(self): return self.render() def render(self, name=None, value=None, attrs=None, choices=()): if self.id_for_label: label_for = format_html(' for="{0}"', self.id_for_label) else: label_for = '' attrs = dict(self.attrs, **attrs) if attrs else self.attrs return format_html( '<label{0}>{1} {2}</label>', label_for, self.tag(attrs), self.choice_label ) def is_checked(self): return self.value == self.choice_value def tag(self, attrs=None): attrs = attrs or self.attrs final_attrs = dict(attrs, type=self.input_type, name=self.name, value=self.choice_value) if self.is_checked(): final_attrs['checked'] = 'checked' return format_html('<input{0} />', flatatt(final_attrs)) @property def id_for_label(self): return self.attrs.get('id', '')
咱們先了解html的radio標籤。html
<form> <label for="male"> <input type="radio" name="sex" id="male"/> Male </label> <br /> <label for="female"> <input type="radio" name="sex" id="female"/> Female </label> </form>
ChoiceInput類,負責輸出一行<label>語句。python
着重看render函數的輸出:函數
return format_html( '<label{0}>{1} {2}</label>', label_for, self.tag(attrs), self.choice_label )
label_for 是html中label標籤中的for屬性。this
self.tag(attrs)負責輸出<input>標籤。spa
choice_label則負責label標籤的展現文本。code
label_for的屬性值是由id_for_label類屬性指定的,id_for_label則是嘗試經過attrs.id屬性。orm
self.attrs.get('id', '')
注意__init__方法中, 若是在attrs參數指定了id, 它會自動添加index參數值的後綴。htm
而後進入函數tag(),增長type, name, value,checked='checked'屬性。get
回到__init__函數, 依次解釋下每一個參數的做用。input
name: 負責input的name屬性
value: 負責判斷checked='checked'屬性
attrs: 負責input的屬性。
choice: 格式爲(choice_value, choice_label), 分別表示input的value屬性和label的文本。
index:負責若是attrs參數指定了id,則添加id的後綴。
class RadioChoiceInput(ChoiceInput): input_type = 'radio' def __init__(self, *args, **kwargs): super(RadioChoiceInput, self).__init__(*args, **kwargs) self.value = force_text(self.value)
RadioChoiceInput從新指定了input_type值, 而且重寫了__init__方法,做用是將value改成文本 格式。
class CheckboxChoiceInput(ChoiceInput): input_type = 'checkbox' def __init__(self, *args, **kwargs): super(CheckboxChoiceInput, self).__init__(*args, **kwargs) self.value = set(force_text(v) for v in self.value) def is_checked(self): return self.choice_value in self.value
CheckboxChoiceInput從新指定input_type值。而且重寫了is_checked( )和__init__方法,由於checkbox是能夠多選的,因此value值是列表型的。