diff --git a/docs/README b/docs/README new file mode 100644 index 0000000..05133d8 --- /dev/null +++ b/docs/README @@ -0,0 +1,17 @@ +The documentation in this tree is in plain text files and can be viewed using +any text file viewer. + +It uses ReST (reStructuredText) [1], and the Sphinx documentation system [2]. +This allows it to be built into other forms for easier viewing and browsing. + +To create an HTML version of the docs: + +* Install Sphinx (using ``sudo pip install Sphinx`` or some other method) + +* In this docs/ directory, type ``make html`` (or ``make.bat html`` on + Windows) at a shell prompt. + +The documentation in _build/html/index.html can then be viewed in a web browser. + +[1] http://docutils.sourceforge.net/rst.html +[2] http://sphinx.pocoo.org/ diff --git a/docs/conf.py b/docs/conf.py index 561ee9e..2b0a04c 100644 --- a/docs/conf.py +++ b/docs/conf.py @@ -249,4 +249,8 @@ texinfo_documents = [ # Example configuration for intersphinx: refer to the Python standard library. -intersphinx_mapping = {'http://docs.python.org/': None} +intersphinx_mapping = { + 'django': ( + 'http://docs.djangoproject.com/en/dev/', + 'http://docs.djangoproject.com/en/dev/_objects/'), +} diff --git a/docs/index.rst b/docs/index.rst index 09987ca..1710cc4 100644 --- a/docs/index.rst +++ b/docs/index.rst @@ -35,6 +35,7 @@ Content contributing design + meta Indices and tables ================== diff --git a/docs/meta.rst b/docs/meta.rst new file mode 100644 index 0000000..d54b050 --- /dev/null +++ b/docs/meta.rst @@ -0,0 +1,288 @@ +==================== +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 ...