Rod*_*ogo 4 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)
Run Code Online (Sandbox Code Playgroud)
我想在Django的管理界面中完成的是使用小部件CheckboxSelectMultiple 渲染Category,但是按类别以SuperCategory分组,如下所示:
类别:
运动:< - SuperCategory项目
[]足球< - 类别项目
[]棒球< - 类别项目
[] ...政治:< - 另一项SuperCategory
[]拉丁美洲
[]北美
[] ......
有没有人对如何做到这一点有一个很好的建议?
非常感谢.
经过一番努力,这就是我得到的.
首先,让ModelAdmin调用ModelForm:
class OptionAdmin(admin.ModelAdmin):
form = forms.OptionForm
Run Code Online (Sandbox Code Playgroud)
然后,在表单中,使用自定义小部件来呈现:
category = forms.ModelMultipleChoiceField(queryset=models.Category.objects.all(),widget=AdminCategoryBySupercategory)
Run Code Online (Sandbox Code Playgroud)
最后,小部件:
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))
Run Code Online (Sandbox Code Playgroud)
不是最优雅的解决方案,但嘿,它的工作原理.
| 归档时间: |
|
| 查看次数: |
1683 次 |
| 最近记录: |