您需要做的是更改由小部件控制的输出。默认是选择小部件,因此您可以对其进行子类化。它看起来像这样:
class Select(Widget):
def __init__(self, attrs=None, choices=()):
super(Select, self).__init__(attrs)
# choices can be any iterable, but we may need to render this widget
# multiple times. Thus, collapse it into a list so it can be consumed
# more than once.
self.choices = list(choices)
def render(self, name, value, attrs=None, choices=()):
if value is None: value = ''
final_attrs = self.build_attrs(attrs, name=name)
output = [u'<select%s>' % flatatt(final_attrs)]
options = self.render_options(choices, [value])
if options:
output.append(options)
output.append('</select>')
return mark_safe(u'\n'.join(output))
def render_options(self, choices, selected_choices):
def render_option(option_value, option_label):
option_value = force_unicode(option_value)
selected_html = (option_value in selected_choices) and u' selected="selected"' or ''
return u'<option value="%s"%s>%s</option>' % (
escape(option_value), selected_html,
conditional_escape(force_unicode(option_label)))
# Normalize to strings.
selected_choices = set([force_unicode(v) for v in selected_choices])
output = []
for option_value, option_label in chain(self.choices, choices):
if isinstance(option_label, (list, tuple)):
output.append(u'<optgroup label="%s">' % escape(force_unicode(option_value)))
for option in option_label:
output.append(render_option(*option))
output.append(u'</optgroup>')
else:
output.append(render_option(option_value, option_label))
return u'\n'.join(output)
这是很多代码。但您需要做的是使用更改的渲染方法来制作您自己的小部件。渲染方法决定了创建的 html。在这种情况下,它是render_options
你需要改变的方法。在这里,您可以包含一些检查来确定何时添加您可以设置样式的类。
另一件事,在上面的代码中,您看起来并没有附加最后的组选择。另外你可能想添加一个order_by()
到查询集,因为您需要按类型排序。您可以在 init 方法中执行此操作,因此在使用表单字段时不必重新执行此操作。