Django在CreateView中禁用/排除字段,但在UpdateView中启用/包含它

时间:2018-06-26 10:20:13

标签: python django django-forms

在创建新对象时,我想排除/禁用Charfield(带有选项和默认值),但是在编辑该对象时,我想启用/包括Charfield供用户更改。

到目前为止,我尝试过this answer的问题是在Stackoverflow上找到的,但这并不是我的完整解决方案。 Charfield确实被禁用,但是当我尝试创建我的对象时,Django总是会告诉我该字段是必需的(即使它具有默认值)。

我的代码:

class OfferCreateForm(forms.ModelForm):
    class Meta:
        model = Offer
        exclude = ['date', 'number']

    def __init__(self, *args, **kwargs):
        request = kwargs.pop("request", None)
        super(OfferCreateForm, self).__init__(*args, **kwargs)
        instance = getattr(self, 'instance', None)
        if instance and instance.pk:
            self.fields['status'].widget.attrs['disabled'] = False
        else:
            self.fields['status'].widget.attrs['disabled'] = True

        self.helper = FormHelper()
        self.helper.form_tag = False
        self.helper.help_text_inline = True
        self.helper.add_layout(Layout(
            Fieldset('Angebot',
                     Row(
                         Div(
                             Field('name'),
                             css_class='col-sm-12'
                         ),
                         Div(
                             Field('category'),
                             css_class='col-sm-6'
                         ),
                         Div(
                             Field('status'),
                             css_class='col-sm-6'
                         ),
                     )),
            Fieldset('Kunde',
                    Row(
                        Div(
                            Field('customer', css_class='selectize'),
                            css_class='col-sm-6'
                        ),
                        Div(
                            Field('receiver', css_class='selectize'),
                            css_class='col-sm-6'
                        ),
                    )),
            Fieldset('Kundeninformation',
                    Row(
                        Div(
                            Field('introduction'),
                            css_class='col-sm-12'
                        ),
                    ),
                ),
            Fieldset('Zusätzliche Informationen',
                    Row(
                        Div(
                            Field('footer'),
                            css_class='col-sm-12',
                        ),

                    ),
                ),
            ))

    def clean_status(self):
        instance = getattr(self, 'instance', None)
        if instance and instance.pk:
            return instance.status
        else:
            return self.cleaned_data['status']

我的模型中的状态字段:

status = models.CharField(default="CREATED", max_length=255, choices=STATUSES, verbose_name="Status")

还请注意:永远不会调用clean_status函数。我尝试在其中进行调试,但显然此功能绝对不起作用。

我知道我可以创建两种不同的形式,但是我想避免这种情况,请不要使用Javascript。

1 个答案:

答案 0 :(得分:2)

您可以从字段列表中完全删除字段,而不必使用fields.pop()方法将其禁用:

def __init__(self, *args, **kwargs):
    request = kwargs.pop("request", None)
    super(OfferCreateForm, self).__init__(*args, **kwargs)
    instance = getattr(self, 'instance', None)
    if instance and instance.pk:
        self.fields.pop('status')

对于div部分,您可以执行以下操作:

divs = [Div(
    Field('name'),
    css_class='col-sm-12'
),
    Div(
        Field('category'),
        css_class='col-sm-6'
    )]

if not instance and not instance.pk:
    divs.append(Div(
        Field('status'),
        css_class='col-sm-6'
    ))

self.helper.add_layout(Layout(
    Fieldset('Angebot',
            Row(*divs)))