我有一个映射到bugs
的{{1}}模型。类别可以拥有其他类别。
categories
我已经在前端视图上使用django-mptt来呈现类别。我想知道如何修改管理视图,这样当我去创建一个新的bug时,我会得到一个带有复选框而不是下拉列表的分层顺序。
类似的东西:
class Bug( models.Model ):
categories = models.ManyToManyField('Category')
name = models.CharField( max_length=100 )
slug = models.SlugField(unique=True)
summary = models.TextField()
summary_markdown = models.TextField(editable=False, blank=True)
date_added = models.DateTimeField(auto_now_add=True)
browser = models.ManyToManyField( Browser )
poster = models.ForeignKey(User)
class Category ( models.Model ):
name = models.CharField( max_length=100 )
slug = models.SlugField(unique=True)
parent = models.ForeignKey( 'self', null=True, blank=True, related_name='children' )
class Meta:
ordering = ['name']
verbose_name_plural = 'Categories'
def __unicode__(self):
return self.name
答案 0 :(得分:1)
我有类似的问题,但使用的布局有点不同。您需要创建一个自定义小部件来显示类别。 这就是我的做法:
from itertools import chain
from django import forms
from django.db import models
from django.forms.widgets import CheckboxSelectMultiple
from django.utils.encoding import force_unicode
from django.utils.html import conditional_escape
from django.utils.safestring import mark_safe
class CustomCheckboxSelectMultiple(forms.CheckboxSelectMultiple):
items_per_row = 1 # Number of items per row
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 = ['<table><tr>']
# Normalize to strings
str_values = set([force_unicode(v) for v in value])
for i, (option_value, option_label) in enumerate(chain(self.choices, choices)):
# If an ID attribute was given, add a numeric index as a suffix,
# so that the checkboxes don't all have the same ID attribute.
if has_id:
final_attrs = dict(final_attrs, id='%s_%s' % (attrs['id'], i))
label_for = ' 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))
if i != 0 and i % self.items_per_row == 0:
output.append('</tr><tr>')
#Here you need to put you layout logic for display the checkboxes
if self.choices[i][1].parent_id is None:
output.append('<td nowrap><label%s>%s</label></td>' % (label_for, option_label))
else:
output.append('<td nowrap><label%s>%s %s</label></td>' % (label_for, rendered_cb, option_label))
output.append('</tr></table>')
return mark_safe('\n'.join(output))
在models.py中我有:
class MyModelForm(ModelForm):
my_model_types = forms.MultipleChoiceField(label='My model types', widget = CustomCheckboxSelectMultiple, required=True)
class Meta:
model = MyModel
def __init__(self, *args, **kwargs):
super(self.__class__, self).__init__(*args, **kwargs)
tree = Tree()
tree.build_tree(reasons=MyModelType.objects.all())
list = tree.as_list()
CHOICES = [(rt.pk, rt) for rt in list]
self.fields['reason_types'].choices = CHOICES