python - 在 Django 中分组 CheckboxSelectMultiple 选项

标签 python django django-admin django-widget

在我的 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 呈现 CategoryCategory 以某种方式按 SuperCategory 分组,像这样:


Category:

Sports: <- Item of SuperCategory
[ ] Soccer <- Item of Category
[ ] Baseball <- Item of Category
[ ] ...

Politics: <- Another item of SuperCategory
[ ] Latin America
[ ] North america
[ ] ...


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

非常感谢。

最佳答案

经过一番努力,这就是我得到的。

首先,让 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))

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

关于python - 在 Django 中分组 CheckboxSelectMultiple 选项,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/5200911/

相关文章:

python - 根据用户输入从 python 中的 .txt 文件中提取信息

python - CondaHTTPError : HTTP 000 CONNECTION FAILED for url <https://repo. continuum.io/pk gs/r/win-64/repodata.json.bz2>

python - 为什么用户信息不使用django附加到mysql数据库?

python - 除非满足条件,否则如何在 Django 管理中不显示删除确认

django - Django管理员: Making a required field read-only

python - 编码值形式.ModelForm

python 到 mysql 尝试异常中的未知列

python - Shopify Python API 和纺织品库存

django - 具有多个内联表单集的基于Django类的CreateView和UpdateView

python - Django 模型 "doesn' t 声明一个显式的 app_label”