Django: Make certain fields in a ModelForm required=False [duplicate]
Asked Answered
C

5

59

How do I make certain fields in a ModelForm required=False?

If I have:

class ThatForm(ModelForm):
  class Meta:
    widgets = {"text": Textarea(required=False)}

Or if I have:

class ThatForm(ModelForm):
  text = Textarea(required=False)

Django returns:

__init__() got an unexpected keyword argument 'required'
Cheat answered 4/6, 2014 at 18:40 Comment(2)
There's no form field type called TextArea, you have to use an ancestor of Field, probably the one called CharField and add a TextArea widgetDeceitful
Would it be possible to set the field to required=False without defining a static field and/or widget type?Cheat
D
92

following from comments. Probably yes:

class ThatForm(ModelForm):
    def __init__(self, *args, **kwargs):
        # first call parent's constructor
        super(ThatForm, self).__init__(*args, **kwargs)
        # there's a `fields` property now
        self.fields['desired_field_name'].required = False
Deceitful answered 4/6, 2014 at 19:1 Comment(1)
@User I dont, but maybe official Django Docs could have: docs.djangoproject.com/en/2.1/ref/forms/fieldsDeceitful
S
50

you ought to add blank=True to the corresponding model

The documentation says

If the model field has blank=True, then required is set to False on the form field. Otherwise, required=True.

Also see the documentation for blank itself.

Sibyl answered 3/7, 2015 at 15:17 Comment(4)
This should be the accepted answer since it is what blank is intended forBavaria
This is not always the solution: Imagine you have a field in a model that is compulsory, but you want to search for objects of that type with or without this restriction. Then you want the form to allow a search without that attribute. For instance you have colour as a required field in the model, but you might want search for objects that have a certain shape, regardless of the colour.Spiel
No solution is always the solution. But the solution I have presented is the best practice that ought to be used unless your situation is unusual (like the one you mentioned). In that case, a separate SO question would make sense. But OP doesn't mention any such situation, the question is very general and so should be the answer.Sibyl
No, this solution is special solution, It’s a very common situation that you have a model with some required fields, e. g. addresses with street, city, country all compulsory, but you want to search with a form (ModelForm) for just a part of the fields, e. g. just city and country. And I understood the OP like that. Your solution, that is very obvious for me, that you define the model fields as blank=True (sometimes in combination with null=True) works just in special cases. The general answer is the one by yedpodtrzitko.Spiel
C
38

When we need to set required option on a bunch of fields we can:

class ThatForm(forms.ModelForm):

    def __init__(self, *args, **kwargs):
        super().__init__(*args, **kwargs)

        for field in self.Meta.required:
            self.fields[field].required = True

    class Meta:
        model = User
        fields = (
            'email',
            'first_name',
            'last_name',
            'address',
            'postcode',
            'city',
            'state',
            'country',
            'company',
            'tax_id',
            'website',
            'service_notifications',
        )
        required = (
            'email',
            'first_name',
            'last_name',
            'address',
            'postcode',
            'city',
            'country',
        )
Calandra answered 28/8, 2018 at 13:55 Comment(7)
Everything works like a charm. @SandeepBalagopal could you explain what exactly went wrong and show error?Calandra
tried this and the fields did not become required. If you look into the options in modelform, modelform is not having such an option github.com/django/django/blob/master/django/forms/…Lemus
@SandeepBalagopal, do you want to tell that people voted here https://mcmap.net/q/327190/-django-make-certain-fields-in-a-modelform-required-false-duplicate and here https://mcmap.net/q/262152/-django-required-field-in-model-form are wrongCalandra
I didn't notice the init method you have overriden. It works. Sorry for the mixup.Lemus
Does anyone know why this is not a standard spec of ModelForms?Galactometer
Great solution. However, I believe that all fields in a ModelForm are required by default, so wouldn't making a selected few "required" in the constructor be redundant? What one would need would be to select the optional ones and set THEM to required = False (leaving the rest in the default state of True).Dabchick
@Dabchick You sad "I believe that all fields in a ModelForm are required by default". But not all. Weather field is required on a ModelForm depends on the field parameters on its Model. And sometimes we need override such behavior by making non required field required.Calandra
F
5

the following may be suitable

class ThatForm(ModelForm):
    text = forms.CharField(required=False, widget=forms.Textarea)
Flounce answered 4/6, 2014 at 19:14 Comment(0)
F
-17

You could try this:

class ThatForm(ModelForm):
  class Meta:
    requireds = 
    {
       'text':False,
    }

requireds must be under Meta.

Feeze answered 1/11, 2017 at 14:0 Comment(1)
Did you actually use this? Because I see no indication in the Django docs or source code, that this would work.Stridulate

© 2022 - 2024 — McMap. All rights reserved.