簡體   English   中英

默認情況下,在ManyToManyField中選擇所有選項

[英]Select all choices in a ManyToManyField by default

默認情況下是否可以通過某種方式在Django中的ManyToManyField生成的選擇倍數中選擇所有選擇?

添加的所有新項目都應在視圖中預先選擇所有選項(也包括添加AnotherEntity新項目時)。

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

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

在上面的示例中,我希望在所有新項目中選擇anotherEntity中的所有選擇。

只需繼承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

您可以像這樣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)

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM