Search code examples
django-modelsdjango-formsmetaclass

How is model Meta class different from model form Meta class?


I wanted to understand the metaclasses we use in the model. I found about it in docs. I remember adding metaclass in model forms as well. It seems like model metaclass and model form metaclass is different. How are they different and what are the meta options in the model form.


Solution

  • In Epistemology, meta is a (ancient) Greek word means about. It is thus a class that says something about the model, or the ModelForm. The name is basically the only thing they have in common.

    The Meta class of a model will specify the verbose name, etc. of a model, constraints and indexes defined in the corresponding database table, etc. The Django documentation has a section that lists all the Meta options for a model.

    The Meta of a ModelForm on the other hand will explain to the ModelForm how it should construct a form for the given model. Normally it the Meta one defines the model for which the ModelForm is constructed together with the fields or exclude that specify what fields to include/exclude respectively. Furthermore the Overriding default fields section of the documentation lists all other Meta options, where a user can (slightly) alter the way how the fields are defined in the ModelForm. The source code [GitHub] also lists all the options for the Meta of ModelForm:

    class ModelFormOptions:
        def __init__(self, options=None):
            self.model = getattr(options, 'model', None)
            self.fields = getattr(options, 'fields', None)
            self.exclude = getattr(options, 'exclude', None)
            self.widgets = getattr(options, 'widgets', None)
            self.localized_fields = getattr(options, 'localized_fields', None)
            self.labels = getattr(options, 'labels', None)
            self.help_texts = getattr(options, 'help_texts', None)
            self.error_messages = getattr(options, 'error_messages', None)
            self.field_classes = getattr(options, 'field_classes', None)