==================== Django's Model._meta ==================== Currently django implements most of its behaviour that makes using models so nice using a metaclass. A metaclass is invoked when an actual class is created and can change that class' behaviour by adding or modifing its attributes and methods. This means that django is actually changing your model class at the moment when the ``models.py`` file of your app is loaded. One of those changes is that the model's metaclass takes the specified ``Meta`` options that the model has attached to and uses it's attributes in conjunction with the model's fields to create a new attribute on the model that is called ``_meta``. This is then responsible for providing an API to access all database related information like the name of the database table or a list of all available fields. Django doesn't currently have an official documentation of the ``_meta``'s semantics, however it is kind of a stable API since many projects and all the db related django internals depend on it. And this page is about documenting the semantics of ``_meta``. Trivia ====== The ``Model._meta`` attribute is an instance of the ``django.db.models.options.Options`` class. It gets attached to the model at that time when the model class is created by the ``django.db.models.base.ModelBase`` metaclass. If ``_meta`` is mentioned we speak about the autogenerated ``_meta`` attribute that is attached to the model class. Some clarifying: In the following text ``Meta`` is referring to the actual ``class Meta:`` definition that the app author has put inside the model class. Like here:: class Restaurant(models.Model): # ... some fields here ... class Meta: ordering = ('name',) Attributes copied from ``Meta`` =============================== .. the django intersphinx link doesn't work :-( Some of ``_meta``'s attributes are just copied from the ``Meta`` options. The following attributes are those. Their behaviour is more detailed described in the :doc:`django documentation `. ``abstract`` A boolean value. See the django documentation on :attr:`~django.db.models.Options.abstract` for more information. ``app_label`` By default it is the name of the app module that the model was created in. This can be overriden in ``Meta`` to make a model part of a specific app. Also see the django documentation about :attr:`~django.db.models.Options.app_label`. ``db_table`` Contains the name of the database table used for this model. This is either what was set on ``Meta`` or defaults to a string that is built from ``app_label`` and ``model_name`` seperated by an underscore. So for example the ``db_table`` for ``django.contrib.auth.models.User`` is ``'auth_user'``. Also see the django documentation about :attr:`~django.db.models.Options.db_table`. ``db_tablespace`` See the django documentation on :attr:`~django.db.models.Options.db_tablespace` for more information. ``get_latest_by`` The name of the field that should be used during ordering to make :meth:`~django.db.models.query.QuerySet.latest` and :meth:`~django.db.models.query.QuerySet.earliest` work. Also see the django documentation about :attr:`~django.db.models.Options.get_latest_by`. ``managed`` If ``managed`` is ``True`` then the :djadmin:`syncdb` management command will take care of creating the database tables. Defaults to ``True``. Also see the django documentation about :attr:`~django.db.models.Options.managed`. ``order_with_respect_to`` See the django documentation on :attr:`~django.db.models.Options.order_with_respect_to` for more information. ``ordering`` See the django documentation on :attr:`~django.db.models.Options.ordering` for more information. ``permissions`` See the django documentation on :attr:`~django.db.models.Options.permissions` for more information. ``proxy`` If set to ``True`` then this model will be treated a :ref:`proxy model `. Also see the django documentation about :attr:`~django.db.models.Options.proxy`. ``index_together`` See the django documentation on :attr:`~django.db.models.Options.index_together` for more information. ``unique_together`` See the django documentation on :attr:`~django.db.models.Options.unique_together` for more information. ``verbose_name`` A human-readable name of the models name, singular. If this is not set in ``Meta``, django will try to guess a human readable name by using the ``object_name`` and inserting appropriate spaces for the CamelCased model name and then making everything lowercase. See the django documentation on :attr:`~django.db.models.Options.verbose_name` for more information. ``verbose_name_plural`` A human-readable name of the models name, plural. If this is not set in ``Meta``, it will default to ``verbose_name`` + ``"s"``. See the django documentation on :attr:`~django.db.models.Options.verbose_name_plural` for more information. Attributes ========== ``abstract_managers`` To handle various inheritance situations, we need to track where managers came from (concrete or abstract base classes). .. ``admin`` Is ``None``. Doesn't seem to be used anywhere. So we don't need to document it. TODO: Create a django ticket to suggest removing it. ``auto_created`` TODO ... ``auto_field`` TODO ... ``concrete_managers`` TODO ... ``concrete_model`` TODO ... ``has_auto_field`` TODO ... ``local_fields`` TODO ... ``local_many_to_many`` TODO ... ``model`` This is the actual ``django.db.models.Model`` that the ``_meta`` attribute is attached to. ``model_name`` TODO ... ``object_name`` It is the actual name of the model class. ``parents`` TODO ... ``pk`` TODO ... ``proxy_for_model`` For any class that is a proxy (including automatically created classes for deferred object loading), ``proxy_for_model`` tells us which class this model is proxying. Note that ``proxy_for_model`` can create a chain of proxy models. For non-proxy models, the variable is always ``None``. ``related_fkey_lookups`` List of all lookups defined in ForeignKey 'limit_choices_to' options from *other* models. Needed for some admin checks. Internal use only. ``swappable`` TODO ... ``virtual_fields`` TODO ... Methods ======= ``module_name(self)`` TODO ... ``add_field(self, field)`` TODO ... ``add_virtual_field(self, field)`` TODO ... ``setup_pk(self, field)`` TODO ... ``pk_index(self)`` TODO ... ``setup_proxy(self, target)`` TODO ... ``verbose_name_raw(self)`` TODO ... ``fields(self)`` TODO ... ``concrete_fields(self)`` TODO ... ``local_concrete_fields(self)`` TODO ... ``get_fields_with_model(self)`` TODO ... ``get_concrete_fields_with_model(self)`` TODO ... ``get_m2m_with_model(self)`` TODO ... ``get_field(self, name, many_to_many=True)`` TODO ... ``get_field_by_name(self, name)`` TODO ... ``get_all_field_names(self)`` TODO ... ``init_name_map(self)`` TODO ... ``get_add_permission(self)`` TODO ... ``get_change_permission(self)`` TODO ... ``get_delete_permission(self)`` TODO ... ``get_all_related_objects(self, local_only=False, include_hidden=False`` TODO ... ``get_all_related_objects_with_model(self, local_only=False`` TODO ... ``get_all_related_many_to_many_objects(self, local_only=False)`` TODO ... ``get_all_related_m2m_objects_with_model(self)`` TODO ... ``get_base_chain(self, model)`` TODO ... ``get_parent_list(self)`` TODO ... ``get_ancestor_link(self, ancestor)`` TODO ...