只需继承SelectMultiple
小部件并覆盖:1)render_option
呈现所有选定的;2)render_options
控制我们在哪里渲染所有选定的以及默认的位置。
class CustomSelectMultiple(SelectMultiple):
def render_options(self, choices, selected_choices):
if not selected_choices:
# there is CreatView and we have no selected choices - render all selected
render_option = self.render_option
else:
# there is UpdateView and we have selected choices - render as default
render_option = super(CustomSelectMultiple, self).render_option
selected_choices = set(force_text(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(format_html('<optgroup label="{0}">', force_text(option_value)))
for option in option_label:
output.append(render_option(selected_choices, *option))
output.append('</optgroup>')
else:
output.append(render_option(selected_choices, option_value, option_label))
return '\n'.join(output)
def render_option(self, selected_choices, option_value, option_label):
option_value = force_text(option_value)
selected_html = mark_safe(' selected="selected"')
return format_html('<option value="{0}"{1}>{2}</option>',
option_value,
selected_html,
force_text(option_label))
然后在表单中将小部件设置为您的字段:
class SomeEntityModelForm(forms.ModelForm):
def __init__(self, *args, **kwargs):
super(SomeEntityModelForm, self).__init__(*args, **kwargs)
self.base_fields['anotherEntity'].widget = CustomSelectMultiple()
class Meta:
model = SomeEntity