28
 15 class Profile(models.Model):
 16     """
 17     User profile model
 18     """
 19     user = models.ForeignKey(User, unique=True)
 20     country = models.CharField('Country', blank=True, null=True, default='',\
 21                                max_length=50, choices=country_list())
 22     is_active = models.BooleanField("Email Activated")

I have a model like above with country set to blank=True, null=True.

However, in the form that is presented to the end user, I required the country field to be completed.

So I redefine the field in the Model Form like this to 'force' it to become required:

 77 class ProfileEditPersonalForm(forms.ModelForm):
 78 
 79     class Meta:
 80         model = Profile
 81         fields = ('email',
 82                   'sec_email',  
 83                   'image',
 84                   'first_name',
 85                   'middle_name',
 86                   'last_name',
 87                   'country',
 88                   'number',
 89                   'fax',)
 90 
 98     country =  forms.ChoiceField(label='Country', choices = country_list())

So the country field is just an example (there are tons of them). Is there a better more DRY way of doing this?

super9
  • 29,181
  • 39
  • 119
  • 172

2 Answers2

78

You can modify the fields in __init__ in the form. This is DRY since the label, queryset and everything else will be used from the model. This can also be useful for overriding other things (e.g. limiting querysets/choices, adding a help text, changing a label, ...).

class ProfileEditPersonalForm(forms.ModelForm):    
    def __init__(self, *args, **kwargs):
        super().__init__(*args, **kwargs)
        self.fields['country'].required = True

    class Meta:
        model = Profile
        fields = (...)

Here is a blog post that describes the same "technique": http://collingrady.wordpress.com/2008/07/24/useful-form-tricks-in-django/

Cesar Canassa
  • 18,659
  • 11
  • 66
  • 69
andreaspelme
  • 3,270
  • 23
  • 12
  • I know `super(ProfileEditPersonalForm, self).__init__(*args, **kwargs)` calls the `forms.ModelForm` parent class `__init__` method but why is it necessary? – super9 Oct 08 '11 at 04:55
  • 5
    In this case, it is necessary to call the super __init__ (i.e. ModelForm.__init__) to set up self.fields for this form instance. It also makes a bunch of other initialization that is necessary to use the form object. This is a standard OO practice, unless you are totally replacing a method, you probably need to call the super class method in some way. – andreaspelme Oct 08 '11 at 07:21
13

In Django 3.0 if you for example want to make email required in user registration form, you can set required=True:

from django import forms
from django.contrib.auth.models import User
from django.contrib.auth.forms import UserCreationForm


class MyForm(UserCreationForm):
    email = forms.EmailField(required=True) # <- set here

    class Meta:
        model = User
        fields = ['username', 'email', 'password1', 'password2']
cikatomo
  • 1,620
  • 2
  • 23
  • 32