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

Nak*_*hon 5 python django django-forms

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

\n\n

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

\n\n

我的代码:

\n\n
class OfferCreateForm(forms.ModelForm):\n    class Meta:\n        model = Offer\n        exclude = [\'date\', \'number\']\n\n    def __init__(self, *args, **kwargs):\n        request = kwargs.pop("request", None)\n        super(OfferCreateForm, self).__init__(*args, **kwargs)\n        instance = getattr(self, \'instance\', None)\n        if instance and instance.pk:\n            self.fields[\'status\'].widget.attrs[\'disabled\'] = False\n        else:\n            self.fields[\'status\'].widget.attrs[\'disabled\'] = True\n\n        self.helper = FormHelper()\n        self.helper.form_tag = False\n        self.helper.help_text_inline = True\n        self.helper.add_layout(Layout(\n            Fieldset(\'Angebot\',\n                     Row(\n                         Div(\n                             Field(\'name\'),\n                             css_class=\'col-sm-12\'\n                         ),\n                         Div(\n                             Field(\'category\'),\n                             css_class=\'col-sm-6\'\n                         ),\n                         Div(\n                             Field(\'status\'),\n                             css_class=\'col-sm-6\'\n                         ),\n                     )),\n            Fieldset(\'Kunde\',\n                    Row(\n                        Div(\n                            Field(\'customer\', css_class=\'selectize\'),\n                            css_class=\'col-sm-6\'\n                        ),\n                        Div(\n                            Field(\'receiver\', css_class=\'selectize\'),\n                            css_class=\'col-sm-6\'\n                        ),\n                    )),\n            Fieldset(\'Kundeninformation\',\n                    Row(\n                        Div(\n                            Field(\'introduction\'),\n                            css_class=\'col-sm-12\'\n                        ),\n                    ),\n                ),\n            Fieldset(\'Zus\xc3\xa4tzliche Informationen\',\n                    Row(\n                        Div(\n                            Field(\'footer\'),\n                            css_class=\'col-sm-12\',\n                        ),\n\n                    ),\n                ),\n            ))\n\n    def clean_status(self):\n        instance = getattr(self, \'instance\', None)\n        if instance and instance.pk:\n            return instance.status\n        else:\n            return self.cleaned_data[\'status\']\n
Run Code Online (Sandbox Code Playgroud)\n\n

我的模型中的状态字段:

\n\n
status = models.CharField(default="CREATED", max_length=255, choices=STATUSES, verbose_name="Status")\n
Run Code Online (Sandbox Code Playgroud)\n\n

另请注意:clean_status 函数永远不会被调用。我尝试在其中进行调试,但显然这个函数什么也没做。

\n\n

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

\n

nev*_*ner 3

您可以从字段列表中完全删除字段,而不是使用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')
Run Code Online (Sandbox Code Playgroud)

至于 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)))
Run Code Online (Sandbox Code Playgroud)