Reputation: 930
I would like to exclude/disable a Charfield (with options and a default value) when creating a new object, but when editing this object, I would like to enable / include the Charfield for the user to change it.
So far I tried this answer I found here on Stackoverflow, but it wasn't the full solution for me. The Charfield did get disabled but when I tried to create my object, Django would always tell me that the field is required (even though it has a Default Value).
My code:
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']
The status field in my model:
status = models.CharField(default="CREATED", max_length=255, choices=STATUSES, verbose_name="Status")
Also note: the clean_status function is never called. I tried to debug in it, but apparently this function does absolutely nothing.
I know I could create two different forms, but I would like to avoid that if possible, also please no Javascript.
Upvotes: 6
Views: 2007
Reputation: 47354
You can completely remove field from fields list instead of disable it using fields.pop()
method:
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')
As for the div part you can do something like this:
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)))
Upvotes: 3