2016-08-31 1 views
0

내가 템플릿에 다음과 같은 형식의 인스턴스를 인쇄 할 경우 :재정 장고의 CheckboxSelectMultiple 위젯 굉장 부트 스트랩 체크 박스

class StrategiesForm(forms.Form): 
    letters = MultipleChoiceField(
     choices=((0, 'a'),(1, 'b'),(2, 'c')), 
     label="a_label", 
     required=True, 
     widget=CheckboxSelectMultiple(), 
    ) 

내가 얻을 :

<label for="id_letters_0">a_label:</label> 
<ul id="id_letters"> 
    <li> 
     <label for="id_letters_0"> 
      <input id="id_letters_0" name="letters" type="checkbox" value="0"> a 
     </label> 
    </li> 
    <li> 
     <label for="id_letters_1"> 
      <input id="id_letters_1" name="letters" type="checkbox" value="1"> b 
     </label> 
    </li> 
    <li> 
     <label for="id_letters_2"> 
      <input id="id_letters_2" name="letters" type="checkbox" value="2"> c 
     </label> 
    </li> 
</ul> 

이 레이블에 포함 된 입력의 무리가 기본적으로 이는 목록 항목에 포함되어 있습니다.

Awesome Bootstrap Checkboxes의 경우 레이아웃을 약간 변경해야합니다. 특히, 입력은 그 안에없는 레이블 위에 있어야합니다. 또한 입력 및 레이블은 li 대신 "checkbox checkbox-primary"클래스를 사용하여 div에 래핑되어야합니다.

위의 예를 들어이 될 것이다 :

<label for="id_letters_0">a_label:</label> 
<div id="id_letters"> 
    <div class="checkbox checkbox-primary"> 
     <input id="id_letters_0" name="letters" type="checkbox" value="0"> a 
     <label for="id_letters_0"></label> 
    </div> 
    <div class="checkbox checkbox-primary"> 
     <input id="id_letters_1" name="letters" type="checkbox" value="1"> b 
     <label for="id_letters_1"></label> 
    </div> 
    <div class="checkbox checkbox-primary"> 
     <input id="id_letters_2" name="letters" type="checkbox" value="2"> c 
     <label for="id_letters_2"></label> 
    </div> 
</div> 

가 어떻게이 작업을 수행 할 수 바람직 장고의 기존을 대체, 새로운 위젯을 정의하여?

+0

나는 또한 장고 - bootstrap3 응용 프로그램을 사용합니다. 위의 위젯이 너무 멋지게 연주된다면 위대 할 것입니다. – mehmet

답변

1

다음은 실행 순서 또는 클래스 계층 구조에서 장고의 기본 코드 :

class CheckboxSelectMultiple(RendererMixin, SelectMultiple): 
    renderer = CheckboxFieldRenderer   # contains all layout logic 
    _empty_value = [] 


class CheckboxFieldRenderer(ChoiceFieldRenderer): # parent has outer layout 
    choice_input_class = CheckboxChoiceInput # contains inner layout 


class ChoiceFieldRenderer(object):    # outer layout: ul and li 
    outer_html = '<ul{id_attr}>{content}</ul>' 
    inner_html = '<li>{choice_value}{sub_widgets}</li>' 

    def render(self):  # this generates inner layout, and wraps with outer 
     ... 

class CheckboxChoiceInput(ChoiceInput): 
    input_type = 'checkbox' 
    ... 


class ChoiceInput(SubWidget):     # inner layout: label and input 
    ... 
    def render(self, name=None, value=None, attrs=None, choices=()): 
     if self.id_for_label: 
      label_for = format_html(' for="{}"', self.id_for_label) 
     else: 
      label_for = '' 
     attrs = dict(self.attrs, **attrs) if attrs else self.attrs 
     return format_html(
      '<label{}>{} {}</label>', label_for, self.tag(attrs), self.choice_label 
     ) 
    ... 

그리고 지금 우리는 역으로 필요한 부분을 오버라이드 (override) :

class AwesomeChoiceInput(ChoiceInput): 
    def render(self, name=None, value=None, attrs=None, choices=()): 
     if self.id_for_label: 
      label_for = format_html(' for="{}"', self.id_for_label) 
     else: 
      label_for = '' 
     attrs = dict(self.attrs, **attrs) if attrs else self.attrs 
     return format_html(
      '{}\n<label{}> {}</label>', self.tag(attrs), label_for, self.choice_label # updated! 
     ) 


class AwesomeChoiceFieldRenderer(ChoiceFieldRenderer): 
    outer_html = '<div{id_attr}>{content}</div>'           # updated!! 
    inner_html = '<div class="checkbox checkbox-primary">{choice_value}{sub_widgets}</div>' # updated!! 
    def __init__(self, name, value, attrs, choices): 
     super().__init__(name, value, attrs, choices) 
     if 'awesome-class' in attrs: 
      self.inner_html = '<div class="checkbox ' + attrs.pop('awesome-class') + '">{choice_value}{sub_widgets}</div>' 

class AwesomeCheckboxChoiceInput(AwesomeChoiceInput, CheckboxChoiceInput): # this was little tricky 
    # there might be better ways of extending a class just to override its parent 
    # summary: class A(B) => class extendedA(extendedB, A) # to get whatever was in A also 
    pass 


class AwesomeCheckboxFieldRenderer(AwesomeChoiceFieldRenderer): # rest-just connect the pipes 
    choice_input_class = AwesomeCheckboxChoiceInput    # as you took off :)        


class AwesomeCheckboxSelectMultiple(CheckboxSelectMultiple): 
    renderer = AwesomeCheckboxFieldRendereraa 
관련 문제