默认情况下,选择ManyToManyField中的所有选项

时间:2014-10-26 21:39:38

标签: django django-models django-forms django-suit

默认情况下是否可以选择Django中ManyToManyField生成的选择倍数内的所有选项?

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

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

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

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

2 个答案:

答案 0 :(得分: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

答案 1 :(得分: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)