========================== Creating forms from models ========================== .. module:: django.forms.models :synopsis: ModelForm and ModelFormset. .. currentmodule:: django.forms ``ModelForm`` ============= .. class:: ModelForm If you're building a database-driven app, chances are you'll have forms that map closely to Django models. For instance, you might have a ``BlogComment`` model, and you want to create a form that lets people submit comments. In this case, it would be redundant to define the field types in your form, because you've already defined the fields in your model. For this reason, Django provides a helper class that lets you create a ``Form`` class from a Django model. For example:: >>> from django.forms import ModelForm >>> from myapp.models import Article # Create the form class. >>> class ArticleForm(ModelForm): ... class Meta: ... model = Article ... fields = ['pub_date', 'headline', 'content', 'reporter'] # Creating a form to add an article. >>> form = ArticleForm() # Creating a form to change an existing article. >>> article = Article.objects.get(pk=1) >>> form = ArticleForm(instance=article) Field types ----------- The generated ``Form`` class will have a form field for every model field specified, in the order specified in the ``fields`` attribute. Each model field has a corresponding default form field. For example, a ``CharField`` on a model is represented as a ``CharField`` on a form. A model ``ManyToManyField`` is represented as a ``MultipleChoiceField``. Here is the full list of conversions: .. currentmodule:: django.db.models =================================== ================================================== Model field Form field =================================== ================================================== :class:`AutoField` Not represented in the form :class:`BigAutoField` Not represented in the form :class:`BigIntegerField` :class:`~django.forms.IntegerField` with ``min_value`` set to -9223372036854775808 and ``max_value`` set to 9223372036854775807. :class:`BooleanField` :class:`~django.forms.BooleanField` :class:`CharField` :class:`~django.forms.CharField` with ``max_length`` set to the model field's ``max_length`` and :attr:`~django.forms.CharField.empty_value` set to ``None`` if ``null=True``. :class:`CommaSeparatedIntegerField` :class:`~django.forms.CharField` :class:`DateField` :class:`~django.forms.DateField` :class:`DateTimeField` :class:`~django.forms.DateTimeField` :class:`DecimalField` :class:`~django.forms.DecimalField` :class:`EmailField` :class:`~django.forms.EmailField` :class:`FileField` :class:`~django.forms.FileField` :class:`FilePathField` :class:`~django.forms.FilePathField` :class:`FloatField` :class:`~django.forms.FloatField` :class:`ForeignKey` :class:`~django.forms.ModelChoiceField` (see below) ``ImageField`` :class:`~django.forms.ImageField` :class:`IntegerField` :class:`~django.forms.IntegerField` ``IPAddressField`` ``IPAddressField`` :class:`GenericIPAddressField` :class:`~django.forms.GenericIPAddressField` :class:`ManyToManyField` :class:`~django.forms.ModelMultipleChoiceField` (see below) :class:`NullBooleanField` :class:`~django.forms.NullBooleanField` :class:`PositiveIntegerField` :class:`~django.forms.IntegerField` :class:`PositiveSmallIntegerField` :class:`~django.forms.IntegerField` :class:`SlugField` :class:`~django.forms.SlugField` :class:`SmallIntegerField` :class:`~django.forms.IntegerField` :class:`TextField` :class:`~django.forms.CharField` with ``widget=forms.Textarea`` :class:`TimeField` :class:`~django.forms.TimeField` :class:`URLField` :class:`~django.forms.URLField` =================================== ================================================== .. currentmodule:: django.forms As you might expect, the ``ForeignKey`` and ``ManyToManyField`` model field types are special cases: * ``ForeignKey`` is represented by ``django.forms.ModelChoiceField``, which is a ``ChoiceField`` whose choices are a model ``QuerySet``. * ``ManyToManyField`` is represented by ``django.forms.ModelMultipleChoiceField``, which is a ``MultipleChoiceField`` whose choices are a model ``QuerySet``. In addition, each generated form field has attributes set as follows: * If the model field has ``blank=True``, then ``required`` is set to ``False`` on the form field. Otherwise, ``required=True``. * The form field's ``label`` is set to the ``verbose_name`` of the model field, with the first character capitalized. * The form field's ``help_text`` is set to the ``help_text`` of the model field. * If the model field has ``choices`` set, then the form field's ``widget`` will be set to ``Select``, with choices coming from the model field's ``choices``. The choices will normally include the blank choice which is selected by default. If the field is required, this forces the user to make a selection. The blank choice will not be included if the model field has ``blank=False`` and an explicit ``default`` value (the ``default`` value will be initially selected instead). Finally, note that you can override the form field used for a given model field. See `Overriding the default fields`_ below. A full example -------------- Consider this set of models:: from django.db import models from django.forms import ModelForm TITLE_CHOICES = ( ('MR', 'Mr.'), ('MRS', 'Mrs.'), ('MS', 'Ms.'), ) class Author(models.Model): name = models.CharField(max_length=100) title = models.CharField(max_length=3, choices=TITLE_CHOICES) birth_date = models.DateField(blank=True, null=True) def __str__(self): # __unicode__ on Python 2 return self.name class Book(models.Model): name = models.CharField(max_length=100) authors = models.ManyToManyField(Author) class AuthorForm(ModelForm): class Meta: model = Author fields = ['name', 'title', 'birth_date'] class BookForm(ModelForm): class Meta: model = Book fields = ['name', 'authors'] With these models, the ``ModelForm`` subclasses above would be roughly equivalent to this (the only difference being the ``save()`` method, which we'll discuss in a moment.):: from django import forms class AuthorForm(forms.Form): name = forms.CharField(max_length=100) title = forms.CharField( max_length=3, widget=forms.Select(choices=TITLE_CHOICES), ) birth_date = forms.DateField(required=False) class BookForm(forms.Form): name = forms.CharField(max_length=100) authors = forms.ModelMultipleChoiceField(queryset=Author.objects.all()) .. _validation-on-modelform: Validation on a ``ModelForm`` ----------------------------- There are two main steps involved in validating a ``ModelForm``: 1. :doc:`Validating the form ` 2. :ref:`Validating the model instance ` Just like normal form validation, model form validation is triggered implicitly when calling :meth:`~django.forms.Form.is_valid()` or accessing the :attr:`~django.forms.Form.errors` attribute and explicitly when calling ``full_clean()``, although you will typically not use the latter method in practice. ``Model`` validation (:meth:`Model.full_clean() `) is triggered from within the form validation step, right after the form's ``clean()`` method is called. .. warning:: The cleaning process modifies the model instance passed to the ``ModelForm`` constructor in various ways. For instance, any date fields on the model are converted into actual date objects. Failed validation may leave the underlying model instance in an inconsistent state and therefore it's not recommended to reuse it. .. _overriding-modelform-clean-method: Overriding the clean() method ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ You can override the ``clean()`` method on a model form to provide additional validation in the same way you can on a normal form. A model form instance attached to a model object will contain an ``instance`` attribute that gives its methods access to that specific model instance. .. warning:: The ``ModelForm.clean()`` method sets a flag that makes the :ref:`model validation ` step validate the uniqueness of model fields that are marked as ``unique``, ``unique_together`` or ``unique_for_date|month|year``. If you would like to override the ``clean()`` method and maintain this validation, you must call the parent class's ``clean()`` method. Interaction with model validation ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ As part of the validation process, ``ModelForm`` will call the ``clean()`` method of each field on your model that has a corresponding field on your form. If you have excluded any model fields, validation will not be run on those fields. See the :doc:`form validation ` documentation for more on how field cleaning and validation work. The model's ``clean()`` method will be called before any uniqueness checks are made. See :ref:`Validating objects ` for more information on the model's ``clean()`` hook. .. _considerations-regarding-model-errormessages: Considerations regarding model's ``error_messages`` ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Error messages defined at the :attr:`form field ` level or at the :ref:`form Meta ` level always take precedence over the error messages defined at the :attr:`model field ` level. Error messages defined on :attr:`model fields ` are only used when the ``ValidationError`` is raised during the :ref:`model validation ` step and no corresponding error messages are defined at the form level. You can override the error messages from ``NON_FIELD_ERRORS`` raised by model validation by adding the :data:`~django.core.exceptions.NON_FIELD_ERRORS` key to the ``error_messages`` dictionary of the ``ModelForm``’s inner ``Meta`` class:: from django.forms import ModelForm from django.core.exceptions import NON_FIELD_ERRORS class ArticleForm(ModelForm): class Meta: error_messages = { NON_FIELD_ERRORS: { 'unique_together': "%(model_name)s's %(field_labels)s are not unique.", } } .. _topics-modelform-save: The ``save()`` method --------------------- Every ``ModelForm`` also has a ``save()`` method. This method creates and saves a database object from the data bound to the form. A subclass of ``ModelForm`` can accept an existing model instance as the keyword argument ``instance``; if this is supplied, ``save()`` will update that instance. If it's not supplied, ``save()`` will create a new instance of the specified model: .. code-block:: python >>> from myapp.models import Article >>> from myapp.forms import ArticleForm # Create a form instance from POST data. >>> f = ArticleForm(request.POST) # Save a new Article object from the form's data. >>> new_article = f.save() # Create a form to edit an existing Article, but use # POST data to populate the form. >>> a = Article.objects.get(pk=1) >>> f = ArticleForm(request.POST, instance=a) >>> f.save() Note that if the form :ref:`hasn't been validated `, calling ``save()`` will do so by checking ``form.errors``. A ``ValueError`` will be raised if the data in the form doesn't validate -- i.e., if ``form.errors`` evaluates to ``True``. If an optional field doesn't appear in the form's data, the resulting model instance uses the model field :attr:`~django.db.models.Field.default`, if there is one, for that field. This behavior doesn't apply to fields that use :class:`~django.forms.CheckboxInput` and :class:`~django.forms.CheckboxSelectMultiple` (or any custom widget whose :meth:`~django.forms.Widget.value_omitted_from_data` method always returns ``False``) since an unchecked checkbox doesn't appear in the data of an HTML form submission. Use a custom form field or widget if you're designing an API and want the default fallback for a :class:`~django.db.models.BooleanField`. .. versionchanged:: 1.10.1 Older versions don't have the exception for :class:`~django.forms.CheckboxInput` which means that unchecked checkboxes receive a value of ``True`` if that's the model field default. .. versionchanged:: 1.10.2 The :meth:`~django.forms.Widget.value_omitted_from_data` method was added. This ``save()`` method accepts an optional ``commit`` keyword argument, which accepts either ``True`` or ``False``. If you call ``save()`` with ``commit=False``, then it will return an object that hasn't yet been saved to the database. In this case, it's up to you to call ``save()`` on the resulting model instance. This is useful if you want to do custom processing on the object before saving it, or if you want to use one of the specialized :ref:`model saving options `. ``commit`` is ``True`` by default. Another side effect of using ``commit=False`` is seen when your model has a many-to-many relation with another model. If your model has a many-to-many relation and you specify ``commit=False`` when you save a form, Django cannot immediately save the form data for the many-to-many relation. This is because it isn't possible to save many-to-many data for an instance until the instance exists in the database. To work around this problem, every time you save a form using ``commit=False``, Django adds a ``save_m2m()`` method to your ``ModelForm`` subclass. After you've manually saved the instance produced by the form, you can invoke ``save_m2m()`` to save the many-to-many form data. For example: .. code-block:: python # Create a form instance with POST data. >>> f = AuthorForm(request.POST) # Create, but don't save the new author instance. >>> new_author = f.save(commit=False) # Modify the author in some way. >>> new_author.some_field = 'some_value' # Save the new instance. >>> new_author.save() # Now, save the many-to-many data for the form. >>> f.save_m2m() Calling ``save_m2m()`` is only required if you use ``save(commit=False)``. When you use a simple ``save()`` on a form, all data -- including many-to-many data -- is saved without the need for any additional method calls. For example: .. code-block:: python # Create a form instance with POST data. >>> a = Author() >>> f = AuthorForm(request.POST, instance=a) # Create and save the new author instance. There's no need to do anything else. >>> new_author = f.save() Other than the ``save()`` and ``save_m2m()`` methods, a ``ModelForm`` works exactly the same way as any other ``forms`` form. For example, the ``is_valid()`` method is used to check for validity, the ``is_multipart()`` method is used to determine whether a form requires multipart file upload (and hence whether ``request.FILES`` must be passed to the form), etc. See :ref:`binding-uploaded-files` for more information. .. _modelforms-selecting-fields: Selecting the fields to use --------------------------- It is strongly recommended that you explicitly set all fields that should be edited in the form using the ``fields`` attribute. Failure to do so can easily lead to security problems when a form unexpectedly allows a user to set certain fields, especially when new fields are added to a model. Depending on how the form is rendered, the problem may not even be visible on the web page. The alternative approach would be to include all fields automatically, or blacklist only some. This fundamental approach is known to be much less secure and has led to serious exploits on major websites (e.g. `GitHub `_). There are, however, two shortcuts available for cases where you can guarantee these security concerns do not apply to you: 1. Set the ``fields`` attribute to the special value ``'__all__'`` to indicate that all fields in the model should be used. For example:: from django.forms import ModelForm class AuthorForm(ModelForm): class Meta: model = Author fields = '__all__' 2. Set the ``exclude`` attribute of the ``ModelForm``’s inner ``Meta`` class to a list of fields to be excluded from the form. For example:: class PartialAuthorForm(ModelForm): class Meta: model = Author exclude = ['title'] Since the ``Author`` model has the 3 fields ``name``, ``title`` and ``birth_date``, this will result in the fields ``name`` and ``birth_date`` being present on the form. If either of these are used, the order the fields appear in the form will be the order the fields are defined in the model, with ``ManyToManyField`` instances appearing last. In addition, Django applies the following rule: if you set ``editable=False`` on the model field, *any* form created from the model via ``ModelForm`` will not include that field. .. note:: Any fields not included in a form by the above logic will not be set by the form's ``save()`` method. Also, if you manually add the excluded fields back to the form, they will not be initialized from the model instance. Django will prevent any attempt to save an incomplete model, so if the model does not allow the missing fields to be empty, and does not provide a default value for the missing fields, any attempt to ``save()`` a ``ModelForm`` with missing fields will fail. To avoid this failure, you must instantiate your model with initial values for the missing, but required fields:: author = Author(title='Mr') form = PartialAuthorForm(request.POST, instance=author) form.save() Alternatively, you can use ``save(commit=False)`` and manually set any extra required fields:: form = PartialAuthorForm(request.POST) author = form.save(commit=False) author.title = 'Mr' author.save() See the `section on saving forms`_ for more details on using ``save(commit=False)``. .. _section on saving forms: `The save() method`_ .. _modelforms-overriding-default-fields: Overriding the default fields ----------------------------- The default field types, as described in the `Field types`_ table above, are sensible defaults. If you have a ``DateField`` in your model, chances are you'd want that to be represented as a ``DateField`` in your form. But ``ModelForm`` gives you the flexibility of changing the form field for a given model. To specify a custom widget for a field, use the ``widgets`` attribute of the inner ``Meta`` class. This should be a dictionary mapping field names to widget classes or instances. For example, if you want the ``CharField`` for the ``name`` attribute of ``Author`` to be represented by a ``