禁用 ModelMultipleChoiceField CheckBoxSelectMultiple Django 中的选择

Ste*_*ith 4 django-templates django-models django-forms django-views python-3.x

全部,

我研究了几天,似乎找不到我要找的东西。我很清楚使用以下方法来禁用 Django 表单中的字段:

self.fields['author'].disabled = True
Run Code Online (Sandbox Code Playgroud)

上述将完全禁用一个字段。我正在尝试显示一个具有多个选择选项的复选框,但我希望自动选择并禁用其中一个选项,以便用户无法将其更改为他们选择的选项之一。这是我用来显示复选框的代码,它工作正常:

self.fields['author'] = forms.ModelMultipleChoiceField(
                        queryset=User.objects.all(),  
                        widget=forms.CheckboxSelectMultiple(),
                        initial = user.favorite)
Run Code Online (Sandbox Code Playgroud)

user.favorite 按我的预期显示,但我想禁用它,以便它仍然处于选中状态,但用户无法更改它,但他们仍然可以在复选框中选择其他内容。这可能吗?提前致谢。

Ana*_*ana 5

我使用重写的一种方法创建了自定义小部件:

MY_OPTION = 0
DISABLED_OPTION = 1
ITEM_CHOICES = [(MY_OPTION, 'My Option'), (DISABLED_OPTION, 'Disabled Option')]

class CheckboxSelectMultipleWithDisabledOption(forms.CheckboxSelectMultiple):

    def create_option(self, *args, **kwargs):
        options_dict = super().create_option(*args, **kwargs)

        if options_dict['value'] == DISABLED_OPTION:
            options_dict['attrs']['disabled'] = ''

        return options_dict
Run Code Online (Sandbox Code Playgroud)

然后采用以下形式:

class MyForm(forms.Form):

    items = forms.MultipleChoiceField()

    def __init__(self, *args, **kwargs):
        super().__init__(*args, **kwargs)
        self.fields['items'].widget = CheckboxSelectMultipleWithDisabledOption()
        self.fields['items'].choices = ITEM_CHOICES
Run Code Online (Sandbox Code Playgroud)

对于更复杂的情况,您可以覆盖自定义小部件__init__并在那里传递其他参数(在我的例子中,我必须传递表单的initial值)。

  • 我想使用这个解决方案,但是当我使用“CheckboxSelectMultipleWithDisabledOption”时,永远不会调用“create_option”方法。如果我使用 SelectMultiple (而不是 CheckboxSelectMultiple)作为父类,则确实会调用方法 `create_option` 。知道为什么吗? (2认同)