Andres
Andres

Reputation: 4501

Django modelform NOT required field

I have a form like this:

class My_Form(ModelForm):
    class Meta:
        model = My_Class
        fields = ('first_name', 'last_name' , 'address')

How can I set the address field as optional?

Upvotes: 114

Views: 127623

Answers (7)

Diego Magalhães
Diego Magalhães

Reputation: 1762

field = models.CharField(max_length=9, default='', blank=True)

Just add blank=True in your model field and it won't be required when you're using modelforms.

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

Adding blank=True to the model also affects Django admin, if your model has null=True and you try to insert a record, the admin form will show an error, with blank=True, the field becomes optional.

source: https://docs.djangoproject.com/en/5.0/topics/forms/modelforms/#field-types

[Edit][1]: Change Django doc link from 4.1 to 5.0
[Edit][2]: Add relevant information about this change to the Django model admin

Upvotes: 30

Akshar Raaj
Akshar Raaj

Reputation: 15231

Guess your model is like this:

class My_Class(models.Model):

    address = models.CharField()

Your form for Django version < 1.8:

class My_Form(ModelForm):

    address = forms.CharField(required=False)

    class Meta:
        model = My_Class
        fields = ('first_name', 'last_name' , 'address')

Your form for Django version > 1.8:

class My_Form(ModelForm):

    address = forms.CharField(blank=True)

    class Meta:
        model = My_Class
        fields = ('first_name', 'last_name' , 'address')

Shameless plug: Check your Python knowledge at http://python.softwarequizzes.com

Upvotes: 123

Vishal Singh
Vishal Singh

Reputation: 801

Solution: use both blank=True, null=True.

my_field = models.PositiveIntegerField(blank=True, null=True)

Explanation:

If you use null=True

my_field = models.PositiveIntegerField(null=True)

then my_field is required, with * next to it in the form and you can't submit the empty value.

If you use blank=True

my_field = models.PositiveIntegerField(blank=True)

then my_field is not required, there won't be a * next to it in the form and you can't submit the value. But it will get null field not allowed.

Note: marking as not required and allowing null fields are two different things.

Pro Tip: Read the error more carefully than documentation.

Upvotes: 6

Filip Savic
Filip Savic

Reputation: 3248

@Anentropic's solution from the comment on @Atma's answer worked for me. And I think it's the best one too.

His comment:

null=True, blank=True will cause the ModelForm field to be required=False

I just set it on my ManyToMany field in my UserProfile class and it worked flawlessly.

My UserProfile class now looks like this (notice the friends field):

class UserProfile(models.Model):
    user = models.OneToOneField(User, on_delete=models.CASCADE)
    friends = models.ManyToManyField('self', null=True, blank=True)

I also think that this is the most beautiful solution since you do the same thing, put null and blank to True, weather you have a simple char field or, like I have, ManyToMany field.

Upvotes: 5

adriaanbd
adriaanbd

Reputation: 357

The above answers are correct; nevertheless due note that setting null=True on a ManyToManyField has no effect at the database level and will raise the following warning when migrating:

(fields.W340) null has no effect on ManyToManyField.

A good answer to this is explained in this other thread.

Upvotes: 0

Atma
Atma

Reputation: 29795

You would have to add:

address = forms.CharField(required=False)

Upvotes: 9

madzohan
madzohan

Reputation: 11808

class My_Form(forms.ModelForm):
    class Meta:
        model = My_Class
        fields = ('first_name', 'last_name' , 'address')

    def __init__(self, *args, **kwargs):
        super(My_Form, self).__init__(*args, **kwargs)
        self.fields['address'].required = False

Upvotes: 149

Related Questions