89
votes

I have a form like this:

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

How can I put the address field as optional?

7
What does the model look like? - Ngenator

7 Answers

117
votes
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
106
votes

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')
20
votes
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."

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

7
votes

You would have to add:

address = forms.CharField(required=False)
5
votes

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 * against it in form, you cant submit empty value.

if you use blank=True

`my_field = models.PositiveIntegerField(blank=True)`

then my_field is not required, no * against it in form, you cant submit value. But will get null field not allowed.

Note:

1) marking as not required and 
2) allowing null field are two different things.

Pro Tip:

Read the error more carefully than documentation.
4
votes

@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.

Again, thanks alot @Anentropic. :)

P.S. I wrote this as a post since I couldn't comment (I have less than 50 reputation) but also because I think his comment needs more exposure.

P.P.S. If this answer helped you, please do upwote his comment.

Cheers :)

0
votes

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.