3

默认情况下是否可以在 Django 中的 ManyToManyField 生成的选择多个中选择所有选项?

添加的所有新项目都应在视图中预先选择所有选项(添加新项目时也是如此AnotherEntity)。

class AnotherEntity(models.Model):
    name = models.CharField()

class SomeEntity(models.Model): 
    anotherEntity = models.ManyToManyField(AnotherEntity)

在上面的示例中,我希望anotherEntity在所有新项目中选择所有选项。

4

2 回答 2

3

只需继承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
于 2014-10-26T21:55:29.403 回答
0

您可以override像这样保存模型的方法:

class SomeEntity(models.Model): 
    anotherEntity = models.ManyToManyField(AnotherEntity)    

    def save(self, *args, **kwargs):
        choices = AnotherEntity.objects.all()
        for choice in choices:
            self.anotherentity.add(choice)
        super(SomeEntity, self).save(*args, **kwargs)
于 2014-10-26T22:12:03.397 回答