Grouping CheckboxSelectMultiple Options in Django

前端 未结 1 714
旧时难觅i
旧时难觅i 2020-12-18 09:15

In my Django App I have the following model:

class SuperCategory(models.Model):
  name = models.CharField(max_length=100,)
  slug = models.SlugField(unique=T         


        
1条回答
  •  没有蜡笔的小新
    2020-12-18 10:02

    After some struggle, here is what I got.

    First, make ModelAdmin call a ModelForm:

    class OptionAdmin(admin.ModelAdmin):
    
       form = forms.OptionForm
    

    Then, in the form, use use a custom widget to render:

    category = forms.ModelMultipleChoiceField(queryset=models.Category.objects.all(),widget=AdminCategoryBySupercategory)    
    

    Finally, the widget:

    class AdminCategoryBySupercategory(forms.CheckboxSelectMultiple):
    
         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'
      '] # Normalize to strings str_values = set([force_unicode(v) for v in value]) supercategories = models.SuperCategory.objects.all() for supercategory in supercategories: output.append(u'
    • %s
    • '%(supercategory.name)) output.append(u'
        ') del self.choices self.choices = [] categories = models.Category.objects.filter(super_category=supercategory) for category in categories: self.choices.append((category.id,category.name)) for i, (option_value, option_label) in enumerate(chain(self.choices, choices)): 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 = forms.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'
      • %s %s
      • ' % (label_for, rendered_cb, option_label)) output.append(u'
      ') output.append(u'') output.append(u'
    ') return mark_safe(u'\n'.join(output))

    Not the most elegant solution, but hey, it worked.

    0 讨论(0)
提交回复
热议问题