【问题标题】:Grouping CheckboxSelectMultiple Options in Django在 Django 中对 CheckboxSelectMultiple 选项进行分组
【发布时间】:2011-07-09 05:24:14
【问题描述】:

在我的 Django 应用程序中,我有以下模型:

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

class Category(models.Model):
  name            = models.CharField(max_length=100,)
  slug            = models.SlugField(unique=True,)
  super_category  = models.ForeignKey(SuperCategory)

我在 Django 的管理界面中尝试完成的是使用小部件 CheckboxSelectMultiple 呈现 Category,但 Category 以某种方式按 SuperCategory 分组,像这样:


类别:

体育: [ ] 足球 [ ] 棒球 [ ] ...

政治: [ ] 拉丁美洲
[ ] 北美
[] ...


有人对如何做到这一点有好的建议吗?

非常感谢。

【问题讨论】:

    标签: python django django-admin django-widget


    【解决方案1】:

    经过一番挣扎,这就是我得到的。

    首先,让ModelAdmin调用一个ModelForm:

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

    然后,在表单中,使用自定义小部件进行渲染:

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

    最后是小部件:

    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'<ul>']
             # 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'<li>%s</li>'%(supercategory.name))
                 output.append(u'<ul>')
                 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'<li><label%s>%s %s</label></li>' % (label_for, rendered_cb, option_label))
                 output.append(u'</ul>')
                 output.append(u'</li>')
             output.append(u'</ul>')
             return mark_safe(u'\n'.join(output))
    

    不是最优雅的解决方案,但嘿,它奏效了。

    【讨论】:

    • 很抱歉重新打开它,但我遇到了同样的问题并使用了您的解决方案,问题在于它在不同的supercategories 中为categories 生成相同的id。我该如何解决?
    猜你喜欢
    • 2012-12-03
    • 2012-11-21
    • 2010-12-31
    • 2017-04-20
    • 2018-08-02
    • 2012-03-19
    • 2015-07-03
    • 2020-11-09
    相关资源
    最近更新 更多