python - Grouping CheckboxSelectMultiple Options in Django -
in django app have following model:
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)
what i'm trying accomplish in django's admin interface rendering of category using widget checkboxselectmultiple category somehow grouped supercategory, this:
category:
sports: <- item of supercategory
[ ] soccer <- item of category
[ ] baseball <- item of category
[ ] ...politics: <- item of supercategory
[ ] latin america
[ ] north america
[ ] ...
does have nice suggestion on how this?
many thanks.
after struggle, here got.
first, make modeladmin call modelform:
class optionadmin(admin.modeladmin): form = forms.optionform
then, in form, use use custom widget render:
category = forms.modelmultiplechoicefield(queryset=models.category.objects.all(),widget=admincategorybysupercategory)
finally, widget:
class admincategorybysupercategory(forms.checkboxselectmultiple): def render(self, name, value, attrs=none, choices=()): if value none: value = [] has_id = attrs , 'id' in attrs final_attrs = self.build_attrs(attrs, name=name) output = [u'<ul>'] # normalize strings str_values = set([force_unicode(v) v in value]) supercategories = models.supercategory.objects.all() 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) category in categories: self.choices.append((category.id,category.name)) 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))
not elegant solution, hey, worked.
Comments
Post a Comment