how to add
tag instead of
  • 前端 未结 4 1830
    [愿得一人]
    [愿得一人] 2020-12-18 05:35

    forms.py

    class TypeSelectionForm(forms.Form):
        checkbox_field = forms.MultipleChoiceField(widget=forms.CheckboxSelectMultiple(), label=\"\", required=Fals         
    
    
            
    相关标签:
    4条回答
    • 2020-12-18 06:14

      This is similar to @bhappy 's solution. The overall solution is to define a custom as_div method and use it as a template filter in your templates. Have a look at this django snippets post: Custom Form Example: Forms for Bootstrap Html - CSS Toolkit

      0 讨论(0)
    • 2020-12-18 06:17

      From the documentation:

      New in Django 1.4.

      For more granular control over the generated markup, you can loop over the radio buttons in the template. Assuming a form myform with a field beatles that uses a RadioSelect as its widget:

      {% for radio in myform.beatles %}
      <div class="myradio">
          {{ radio }}
      </div>
      {% endfor %}
      

      In your template, you should have this:

      {% for radio in types.checkbox_field %}
         <input style="margin: 8px -3px;float: left;" type="button" class="delete_types" id="delete_name"/>{{ radio }}
      {% endfor %}
      

      You should also use a ModelMultipleChoiceField:

      class TypeSelectionForm(forms.Form):
          checkbox_field = forms.ModelMultipleChoiceField(label="",
                                                          queryset=Types.objects.none(),
                                                          required=False)
      
          def __init__(self, *args, **kwargs):
              qs = kwargs.pop('queryset')
              super(TypeSelectionForm, self).__init__(*args, **kwargs)
              self.fields['checkbox_field'].queryset = qs
      

      Initiate it like this from your view:

      def types(method):
          """"""""""""
          qs = Types.objects.filter(parent_type_id=type_id,is_active=True)
          types = TypeSelectionForm(queryset=qs)
          return render(request,'types.html',{'types':'types'})
      
      0 讨论(0)
    • 2020-12-18 06:21

      Widgets take an attrs attribute, which should add the attribute to each input. Try this:

      checkbox_field = forms.MultipleChoiceField(widget=forms.CheckboxSelectMultiple(attrs={'class': 'my-image-class', }), label="", required=False)
      

      UPDATE:

      So it looks like the granular approach mentioned above only works for radio button widgets. But what you want is actually very simple. Just output your checkboxes as normal:

      {% for field in types.checkbox_field %}                                 
       {{field}}
      {% endfor %}
      

      This will output your list of checkboxes as you need. Then just use a little CSS to style the background image of each list item:

      form ul li {
      background:url("<my-image>") no-repeat center;
      width:20px;
      height:20px;
      

      }

      UPDATE

      If you want to render the checkboxes differently, you need a custom widget class, as that's the widgets job. Something like this will get you going. I'd personally use the attrs option on the widget to add in a class, but I've hard coded it here to show you that what you ask is possible, just not pretty:

      class CheckboxDivSelectMultiple(CheckboxSelectMultiple):
      '''renders the checkboxes as divs with a hard coded class'''
      
      def render(self, name, value, attrs=None, choices=()):
          if value is None: value = []
          has_id = attrs and 'id' in attrs
          final_attrs = self.build_attrs(attrs, name=name)
          output = [u'<div>']
          # Normalize to strings
          str_values = set([force_unicode(v) for v in value])
          for i, (option_value, option_label) in enumerate(chain(self.choices, choices)):
              # If an ID attribute was given, add a numeric index as a suffix,
              # so that the checkboxes don't all have the same ID attribute.
              if has_id:
                  final_attrs = dict(final_attrs, id='%s_%s' % (attrs['id'], i))
                  label_for = u' for="%s"' % final_attrs['id']
              else:
                  label_for = ''
      
              cb = CheckboxInput(final_attrs, check_test=lambda value: value in str_values)
              option_value = force_unicode(option_value)
              rendered_cb = cb.render(name, option_value)
              option_label = conditional_escape(force_unicode(option_label))
              output.append(u'<div class="%s"><label%s>%s %s</label></div>' % ('new-class', label_for, rendered_cb, option_label))
          output.append(u'</div>')
          return mark_safe(u'\n'.join(output))
      

      use it in your form:

      checkbox_field = forms.MultipleChoiceField(widget=forms.CheckboxDivSelectMultiple(), label="", required=False)
      
      0 讨论(0)
    • 2020-12-18 06:22

      Why not use the power of Django template tags ?

      from django import template
      from django.utils.safestring import mark_safe
      register = template.Library()
      
      
      @register.filter("as_div")
      def as_div(form):
          form_as_div = form.as_ul().replace("<ul", "<div").replace("</ul", "</div")
          form_as_div = form_as_div.replace("<li", "<div").replace("</li", "</div")
          return mark_safe(form_as_div)
      

      Put that in a template tag and then do this simply in your template

      {% load ad_div %}
      
      {# some Code #}
      
      {{ form|as_div }}
      
      {# some other code #} 
      

      ============================

      Other approach (Better Cleaner)

      Another approach would be to extend django forms model

      as follows

      from django.forms.forms import BaseForm
      
      Class AsDiv(BaseForm):
      
      def as_div(self):
              return self._html_output(
                  normal_row = u'<div%(html_class_attr)s>%(errors)s%(label)s %(field)s%(help_text)s</div>',
                  error_row = u'<div>%s</div>',
                  row_ender = '</div>',
                  help_text_html = u' <span class="helptext">%s</span>',
                  errors_on_separate_row = False)
      

      Then you could just do this is your template

      {{ form.as_div }} 
      
      0 讨论(0)
    提交回复
    热议问题