Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/django/20.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 分组复选框选择Django中的多个选项_Python_Django_Django Admin_Django Widget - Fatal编程技术网

Python 分组复选框选择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

在我的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的管理界面中实现的是使用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
。我怎样才能解决这个问题?