Python 分组复选框选择Django中的多个选项
在我的Django应用程序中,我有以下型号:Python 分组复选框选择Django中的多个选项,python,django,django-admin,django-widget,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 = mode
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的管理界面中实现的是使用widget CheckboxSelectMultiple呈现类别,但使用类别以某种方式按超级类别进行分组,如下所示:
类别:
体育:经过一番挣扎后,我得到的是 首先,让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))
class AdminCategoryBySupercategory(forms.CheckboxSelectMultiple):
def render(self、name、value、attrs=None、choices=()):
如果值为None:value=[]
在属性中有\u id=attrs和'id'
final\u attrs=self.build\u attrs(attrs,name=name)
输出=[u'']
#规范化为字符串
str_values=set([force_unicode(v)表示值中的v])
supercategories=models.SuperCategory.objects.all()
对于超级类别中的超级类别:
output.append(u'- %s
'%(supercategory.name))
output.append(u'')
自我选择
self.choices=[]
类别=模型.类别.对象.过滤器(超级类别=超级类别)
对于类别中的类别:
self.choices.append((category.id,category.name))
对于枚举(链(self.choices,choices))中的i(选项值,选项标签):
如果您有您的id:
final_attrs=dict(final_attrs,id='%s_%s'(attrs['id'],i))
label_for=u'for=“%s”'%final_attrs['id']
其他:
标签_为=“”
cb=forms.CheckboxInput(最终属性,检查测试=lambda值:str值中的值)
选项\u值=强制\u unicode(选项\u值)
rendered\u cb=cb.render(名称、选项\u值)
选项标签=条件转义(强制unicode(选项标签))
output.append(u'- %s%s
'%(标签、呈现的cb、选项标签))
output.append(u'
')
output.append(u'')
output.append(u'
')
返回标记\u safe(u'\n'.连接(输出))
这不是最优雅的解决方案,但是,嘿,它成功了。很抱歉重新打开它,但我遇到了同样的问题,并且使用了您的解决方案,问题是它在不同的
超级类别中为类别
生成了相同的id
。我怎样才能解决这个问题?