diff options
Diffstat (limited to 'parts/django/docs/topics/db/models.txt')
-rw-r--r-- | parts/django/docs/topics/db/models.txt | 1234 |
1 files changed, 1234 insertions, 0 deletions
diff --git a/parts/django/docs/topics/db/models.txt b/parts/django/docs/topics/db/models.txt new file mode 100644 index 0000000..2a19cbd --- /dev/null +++ b/parts/django/docs/topics/db/models.txt @@ -0,0 +1,1234 @@ +====== +Models +====== + +.. module:: django.db.models + +A model is the single, definitive source of data about your data. It contains +the essential fields and behaviors of the data you're storing. Generally, each +model maps to a single database table. + +The basics: + + * Each model is a Python class that subclasses + :class:`django.db.models.Model`. + + * Each attribute of the model represents a database field. + + * With all of this, Django gives you an automatically-generated + database-access API; see :doc:`/topics/db/queries`. + +.. seealso:: + + A companion to this document is the `official repository of model + examples`_. (In the Django source distribution, these examples are in the + ``tests/modeltests`` directory.) + + .. _official repository of model examples: http://www.djangoproject.com/documentation/models/ + +Quick example +============= + +This example model defines a ``Person``, which has a ``first_name`` and +``last_name``:: + + from django.db import models + + class Person(models.Model): + first_name = models.CharField(max_length=30) + last_name = models.CharField(max_length=30) + +``first_name`` and ``last_name`` are fields_ of the model. Each field is +specified as a class attribute, and each attribute maps to a database column. + +The above ``Person`` model would create a database table like this: + +.. code-block:: sql + + CREATE TABLE myapp_person ( + "id" serial NOT NULL PRIMARY KEY, + "first_name" varchar(30) NOT NULL, + "last_name" varchar(30) NOT NULL + ); + +Some technical notes: + + * The name of the table, ``myapp_person``, is automatically derived from + some model metadata but can be overridden. See :ref:`table-names` for more + details.. + + * An ``id`` field is added automatically, but this behavior can be + overridden. See :ref:`automatic-primary-key-fields`. + + * The ``CREATE TABLE`` SQL in this example is formatted using PostgreSQL + syntax, but it's worth noting Django uses SQL tailored to the database + backend specified in your :doc:`settings file </topics/settings>`. + +Using models +============ + +Once you have defined your models, you need to tell Django you're going to *use* +those models. Do this by editing your settings file and changing the +:setting:`INSTALLED_APPS` setting to add the name of the module that contains +your ``models.py``. + +For example, if the models for your application live in the module +``mysite.myapp.models`` (the package structure that is created for an +application by the :djadmin:`manage.py startapp <startapp>` script), +:setting:`INSTALLED_APPS` should read, in part:: + + INSTALLED_APPS = ( + #... + 'mysite.myapp', + #... + ) + +When you add new apps to :setting:`INSTALLED_APPS`, be sure to run +:djadmin:`manage.py syncdb <syncdb>`. + +Fields +====== + +The most important part of a model -- and the only required part of a model -- +is the list of database fields it defines. Fields are specified by class +attributes. + +Example:: + + class Musician(models.Model): + first_name = models.CharField(max_length=50) + last_name = models.CharField(max_length=50) + instrument = models.CharField(max_length=100) + + class Album(models.Model): + artist = models.ForeignKey(Musician) + name = models.CharField(max_length=100) + release_date = models.DateField() + num_stars = models.IntegerField() + +Field types +----------- + +Each field in your model should be an instance of the appropriate +:class:`~django.db.models.Field` class. Django uses the field class types to +determine a few things: + + * The database column type (e.g. ``INTEGER``, ``VARCHAR``). + + * The :doc:`widget </ref/forms/widgets>` to use in Django's admin interface, + if you care to use it (e.g. ``<input type="text">``, ``<select>``). + + * The minimal validation requirements, used in Django's admin and in + automatically-generated forms. + +Django ships with dozens of built-in field types; you can find the complete list +in the :ref:`model field reference <model-field-types>`. You can easily write +your own fields if Django's built-in ones don't do the trick; see +:doc:`/howto/custom-model-fields`. + +Field options +------------- + +Each field takes a certain set of field-specific arguments (documented in the +:ref:`model field reference <model-field-types>`). For example, +:class:`~django.db.models.CharField` (and its subclasses) require a +:attr:`~django.db.models.CharField.max_length` argument which specifies the size +of the ``VARCHAR`` database field used to store the data. + +There's also a set of common arguments available to all field types. All are +optional. They're fully explained in the :ref:`reference +<common-model-field-options>`, but here's a quick summary of the most often-used +ones: + + :attr:`~Field.null` + If ``True``, Django will store empty values as ``NULL`` in the database. + Default is ``False``. + + :attr:`~Field.blank` + If ``True``, the field is allowed to be blank. Default is ``False``. + + Note that this is different than :attr:`~Field.null`. + :attr:`~Field.null` is purely database-related, whereas + :attr:`~Field.blank` is validation-related. If a field has + :attr:`blank=True <Field.blank>`, validation on Django's admin site will + allow entry of an empty value. If a field has :attr:`blank=False + <Field.blank>`, the field will be required. + + :attr:`~Field.choices` + An iterable (e.g., a list or tuple) of 2-tuples to use as choices for + this field. If this is given, Django's admin will use a select box + instead of the standard text field and will limit choices to the choices + given. + + A choices list looks like this:: + + YEAR_IN_SCHOOL_CHOICES = ( + (u'FR', u'Freshman'), + (u'SO', u'Sophomore'), + (u'JR', u'Junior'), + (u'SR', u'Senior'), + (u'GR', u'Graduate'), + ) + + The first element in each tuple is the value that will be stored in the + database, the second element will be displayed by the admin interface, + or in a ModelChoiceField. Given an instance of a model object, the + display value for a choices field can be accessed using the + ``get_FOO_display`` method. For example:: + + from django.db import models + + class Person(models.Model): + GENDER_CHOICES = ( + (u'M', u'Male'), + (u'F', u'Female'), + ) + name = models.CharField(max_length=60) + gender = models.CharField(max_length=2, choices=GENDER_CHOICES) + + :: + + >>> p = Person(name="Fred Flinstone", gender="M") + >>> p.save() + >>> p.gender + u'M' + >>> p.get_gender_display() + u'Male' + + :attr:`~Field.default` + The default value for the field. This can be a value or a callable + object. If callable it will be called every time a new object is + created. + + :attr:`~Field.help_text` + Extra "help" text to be displayed under the field on the object's admin + form. It's useful for documentation even if your object doesn't have an + admin form. + + :attr:`~Field.primary_key` + If ``True``, this field is the primary key for the model. + + If you don't specify :attr:`primary_key=True <Field.primary_key>` for + any fields in your model, Django will automatically add an + :class:`IntegerField` to hold the primary key, so you don't need to set + :attr:`primary_key=True <Field.primary_key>` on any of your fields + unless you want to override the default primary-key behavior. For more, + see :ref:`automatic-primary-key-fields`. + + :attr:`~Field.unique` + If ``True``, this field must be unique throughout the table. + +Again, these are just short descriptions of the most common field options. Full +details can be found in the :ref:`common model field option reference +<common-model-field-options>`. + +.. _automatic-primary-key-fields: + +Automatic primary key fields +---------------------------- + +By default, Django gives each model the following field:: + + id = models.AutoField(primary_key=True) + +This is an auto-incrementing primary key. + +If you'd like to specify a custom primary key, just specify +:attr:`primary_key=True <Field.primary_key>` on one of your fields. If Django +sees you've explicitly set :attr:`Field.primary_key`, it won't add the automatic +``id`` column. + +Each model requires exactly one field to have :attr:`primary_key=True +<Field.primary_key>`. + +.. _verbose-field-names: + +Verbose field names +------------------- + +Each field type, except for :class:`~django.db.models.ForeignKey`, +:class:`~django.db.models.ManyToManyField` and +:class:`~django.db.models.OneToOneField`, takes an optional first positional +argument -- a verbose name. If the verbose name isn't given, Django will +automatically create it using the field's attribute name, converting underscores +to spaces. + +In this example, the verbose name is ``"person's first name"``:: + + first_name = models.CharField("person's first name", max_length=30) + +In this example, the verbose name is ``"first name"``:: + + first_name = models.CharField(max_length=30) + +:class:`~django.db.models.ForeignKey`, +:class:`~django.db.models.ManyToManyField` and +:class:`~django.db.models.OneToOneField` require the first argument to be a +model class, so use the :attr:`~Field.verbose_name` keyword argument:: + + poll = models.ForeignKey(Poll, verbose_name="the related poll") + sites = models.ManyToManyField(Site, verbose_name="list of sites") + place = models.OneToOneField(Place, verbose_name="related place") + +The convention is not to capitalize the first letter of the +:attr:`~Field.verbose_name`. Django will automatically capitalize the first +letter where it needs to. + +Relationships +------------- + +Clearly, the power of relational databases lies in relating tables to each +other. Django offers ways to define the three most common types of database +relationships: many-to-one, many-to-many and one-to-one. + +Many-to-one relationships +~~~~~~~~~~~~~~~~~~~~~~~~~ + +To define a many-to-one relationship, use :class:`~django.db.models.ForeignKey`. +You use it just like any other :class:`~django.db.models.Field` type: by +including it as a class attribute of your model. + +:class:`~django.db.models.ForeignKey` requires a positional argument: the class +to which the model is related. + +For example, if a ``Car`` model has a ``Manufacturer`` -- that is, a +``Manufacturer`` makes multiple cars but each ``Car`` only has one +``Manufacturer`` -- use the following definitions:: + + class Manufacturer(models.Model): + # ... + + class Car(models.Model): + manufacturer = models.ForeignKey(Manufacturer) + # ... + +You can also create :ref:`recursive relationships <recursive-relationships>` (an +object with a many-to-one relationship to itself) and :ref:`relationships to +models not yet defined <lazy-relationships>`; see :ref:`the model field +reference <ref-foreignkey>` for details. + +It's suggested, but not required, that the name of a +:class:`~django.db.models.ForeignKey` field (``manufacturer`` in the example +above) be the name of the model, lowercase. You can, of course, call the field +whatever you want. For example:: + + class Car(models.Model): + company_that_makes_it = models.ForeignKey(Manufacturer) + # ... + +.. seealso:: + + See the `Many-to-one relationship model example`_ for a full example. + +.. _Many-to-one relationship model example: http://www.djangoproject.com/documentation/models/many_to_one/ + +:class:`~django.db.models.ForeignKey` fields also accept a number of extra +arguments which are explained in :ref:`the model field reference +<foreign-key-arguments>`. These options help define how the relationship should +work; all are optional. + +Many-to-many relationships +~~~~~~~~~~~~~~~~~~~~~~~~~~ + +To define a many-to-many relationship, use +:class:`~django.db.models.ManyToManyField`. You use it just like any other +:class:`~django.db.models.Field` type: by including it as a class attribute of +your model. + +:class:`~django.db.models.ManyToManyField` requires a positional argument: the +class to which the model is related. + +For example, if a ``Pizza`` has multiple ``Topping`` objects -- that is, a +``Topping`` can be on multiple pizzas and each ``Pizza`` has multiple toppings +-- here's how you'd represent that:: + + class Topping(models.Model): + # ... + + class Pizza(models.Model): + # ... + toppings = models.ManyToManyField(Topping) + +As with :class:`~django.db.models.ForeignKey`, you can also create +:ref:`recursive relationships <recursive-relationships>` (an object with a +many-to-many relationship to itself) and :ref:`relationships to models not yet +defined <lazy-relationships>`; see :ref:`the model field reference +<ref-manytomany>` for details. + +It's suggested, but not required, that the name of a +:class:`~django.db.models.ManyToManyField` (``toppings`` in the example above) +be a plural describing the set of related model objects. + +It doesn't matter which model gets the +:class:`~django.db.models.ManyToManyField`, but you only need it in one of the +models -- not in both. + +Generally, :class:`~django.db.models.ManyToManyField` instances should go in the +object that's going to be edited in the admin interface, if you're using +Django's admin. In the above example, ``toppings`` is in ``Pizza`` (rather than +``Topping`` having a ``pizzas`` :class:`~django.db.models.ManyToManyField` ) +because it's more natural to think about a pizza having toppings than a +topping being on multiple pizzas. The way it's set up above, the ``Pizza`` admin +form would let users select the toppings. + +.. seealso:: + + See the `Many-to-many relationship model example`_ for a full example. + +.. _Many-to-many relationship model example: http://www.djangoproject.com/documentation/models/many_to_many/ + +:class:`~django.db.models.ManyToManyField` fields also accept a number of extra +arguments which are explained in :ref:`the model field reference +<manytomany-arguments>`. These options help define how the relationship should +work; all are optional. + +.. _intermediary-manytomany: + +Extra fields on many-to-many relationships +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +.. versionadded:: 1.0 + +When you're only dealing with simple many-to-many relationships such as +mixing and matching pizzas and toppings, a standard :class:`~django.db.models.ManyToManyField` is all you need. However, sometimes +you may need to associate data with the relationship between two models. + +For example, consider the case of an application tracking the musical groups +which musicians belong to. There is a many-to-many relationship between a person +and the groups of which they are a member, so you could use a +:class:`~django.db.models.ManyToManyField` to represent this relationship. +However, there is a lot of detail about the membership that you might want to +collect, such as the date at which the person joined the group. + +For these situations, Django allows you to specify the model that will be used +to govern the many-to-many relationship. You can then put extra fields on the +intermediate model. The intermediate model is associated with the +:class:`~django.db.models.ManyToManyField` using the +:attr:`through <ManyToManyField.through>` argument to point to the model +that will act as an intermediary. For our musician example, the code would look +something like this:: + + class Person(models.Model): + name = models.CharField(max_length=128) + + def __unicode__(self): + return self.name + + class Group(models.Model): + name = models.CharField(max_length=128) + members = models.ManyToManyField(Person, through='Membership') + + def __unicode__(self): + return self.name + + class Membership(models.Model): + person = models.ForeignKey(Person) + group = models.ForeignKey(Group) + date_joined = models.DateField() + invite_reason = models.CharField(max_length=64) + +When you set up the intermediary model, you explicitly specify foreign +keys to the models that are involved in the ManyToMany relation. This +explicit declaration defines how the two models are related. + +There are a few restrictions on the intermediate model: + + * Your intermediate model must contain one - and *only* one - foreign key + to the target model (this would be ``Person`` in our example). If you + have more than one foreign key, a validation error will be raised. + + * Your intermediate model must contain one - and *only* one - foreign key + to the source model (this would be ``Group`` in our example). If you + have more than one foreign key, a validation error will be raised. + + * The only exception to this is a model which has a many-to-many + relationship to itself, through an intermediary model. In this + case, two foreign keys to the same model are permitted, but they + will be treated as the two (different) sides of the many-to-many + relation. + + * When defining a many-to-many relationship from a model to + itself, using an intermediary model, you *must* use + :attr:`symmetrical=False <ManyToManyField.symmetrical>` (see + :ref:`the model field reference <manytomany-arguments>`). + +Now that you have set up your :class:`~django.db.models.ManyToManyField` to use +your intermediary model (``Membership``, in this case), you're ready to start +creating some many-to-many relationships. You do this by creating instances of +the intermediate model:: + + >>> ringo = Person.objects.create(name="Ringo Starr") + >>> paul = Person.objects.create(name="Paul McCartney") + >>> beatles = Group.objects.create(name="The Beatles") + >>> m1 = Membership(person=ringo, group=beatles, + ... date_joined=date(1962, 8, 16), + ... invite_reason= "Needed a new drummer.") + >>> m1.save() + >>> beatles.members.all() + [<Person: Ringo Starr>] + >>> ringo.group_set.all() + [<Group: The Beatles>] + >>> m2 = Membership.objects.create(person=paul, group=beatles, + ... date_joined=date(1960, 8, 1), + ... invite_reason= "Wanted to form a band.") + >>> beatles.members.all() + [<Person: Ringo Starr>, <Person: Paul McCartney>] + +Unlike normal many-to-many fields, you *can't* use ``add``, ``create``, +or assignment (i.e., ``beatles.members = [...]``) to create relationships:: + + # THIS WILL NOT WORK + >>> beatles.members.add(john) + # NEITHER WILL THIS + >>> beatles.members.create(name="George Harrison") + # AND NEITHER WILL THIS + >>> beatles.members = [john, paul, ringo, george] + +Why? You can't just create a relationship between a ``Person`` and a ``Group`` +- you need to specify all the detail for the relationship required by the +``Membership`` model. The simple ``add``, ``create`` and assignment calls +don't provide a way to specify this extra detail. As a result, they are +disabled for many-to-many relationships that use an intermediate model. +The only way to create this type of relationship is to create instances of the +intermediate model. + +The :meth:`~django.db.models.fields.related.RelatedManager.remove` method is +disabled for similar reasons. However, the +:meth:`~django.db.models.fields.related.RelatedManager.clear` method can be +used to remove all many-to-many relationships for an instance:: + + # Beatles have broken up + >>> beatles.members.clear() + +Once you have established the many-to-many relationships by creating instances +of your intermediate model, you can issue queries. Just as with normal +many-to-many relationships, you can query using the attributes of the +many-to-many-related model:: + + # Find all the groups with a member whose name starts with 'Paul' + >>> Group.objects.filter(members__name__startswith='Paul') + [<Group: The Beatles>] + +As you are using an intermediate model, you can also query on its attributes:: + + # Find all the members of the Beatles that joined after 1 Jan 1961 + >>> Person.objects.filter( + ... group__name='The Beatles', + ... membership__date_joined__gt=date(1961,1,1)) + [<Person: Ringo Starr] + + +One-to-one relationships +~~~~~~~~~~~~~~~~~~~~~~~~ + +To define a one-to-one relationship, use +:class:`~django.db.models.OneToOneField`. You use it just like any other +``Field`` type: by including it as a class attribute of your model. + +This is most useful on the primary key of an object when that object "extends" +another object in some way. + +:class:`~django.db.models.OneToOneField` requires a positional argument: the +class to which the model is related. + +For example, if you were building a database of "places", you would +build pretty standard stuff such as address, phone number, etc. in the +database. Then, if you wanted to build a database of restaurants on +top of the places, instead of repeating yourself and replicating those +fields in the ``Restaurant`` model, you could make ``Restaurant`` have +a :class:`~django.db.models.OneToOneField` to ``Place`` (because a +restaurant "is a" place; in fact, to handle this you'd typically use +:ref:`inheritance <model-inheritance>`, which involves an implicit +one-to-one relation). + +As with :class:`~django.db.models.ForeignKey`, a +:ref:`recursive relationship <recursive-relationships>` +can be defined and +:ref:`references to as-yet undefined models <lazy-relationships>` +can be made; see :ref:`the model field reference <ref-onetoone>` for details. + +.. seealso:: + + See the `One-to-one relationship model example`_ for a full example. + +.. _One-to-one relationship model example: http://www.djangoproject.com/documentation/models/one_to_one/ + +.. versionadded:: 1.0 + +:class:`~django.db.models.OneToOneField` fields also accept one optional argument +described in the :ref:`model field reference <ref-onetoone>`. + +:class:`~django.db.models.OneToOneField` classes used to automatically become +the primary key on a model. This is no longer true (although you can manually +pass in the :attr:`~django.db.models.Field.primary_key` argument if you like). +Thus, it's now possible to have multiple fields of type +:class:`~django.db.models.OneToOneField` on a single model. + +Models across files +------------------- + +It's perfectly OK to relate a model to one from another app. To do this, +import the related model at the top of the model that holds your model. Then, +just refer to the other model class wherever needed. For example:: + + from geography.models import ZipCode + + class Restaurant(models.Model): + # ... + zip_code = models.ForeignKey(ZipCode) + +Field name restrictions +----------------------- + +Django places only two restrictions on model field names: + + 1. A field name cannot be a Python reserved word, because that would result + in a Python syntax error. For example:: + + class Example(models.Model): + pass = models.IntegerField() # 'pass' is a reserved word! + + 2. A field name cannot contain more than one underscore in a row, due to + the way Django's query lookup syntax works. For example:: + + class Example(models.Model): + foo__bar = models.IntegerField() # 'foo__bar' has two underscores! + +These limitations can be worked around, though, because your field name doesn't +necessarily have to match your database column name. See the +:attr:`~Field.db_column` option. + +SQL reserved words, such as ``join``, ``where`` or ``select``, *are* allowed as +model field names, because Django escapes all database table names and column +names in every underlying SQL query. It uses the quoting syntax of your +particular database engine. + +Custom field types +------------------ + +.. versionadded:: 1.0 + +If one of the existing model fields cannot be used to fit your purposes, or if +you wish to take advantage of some less common database column types, you can +create your own field class. Full coverage of creating your own fields is +provided in :doc:`/howto/custom-model-fields`. + +.. _meta-options: + +Meta options +============ + +Give your model metadata by using an inner ``class Meta``, like so:: + + class Ox(models.Model): + horn_length = models.IntegerField() + + class Meta: + ordering = ["horn_length"] + verbose_name_plural = "oxen" + +Model metadata is "anything that's not a field", such as ordering options +(:attr:`~Options.ordering`), database table name (:attr:`~Options.db_table`), or +human-readable singular and plural names (:attr:`~Options.verbose_name` and +:attr:`~Options.verbose_name_plural`). None are required, and adding ``class +Meta`` to a model is completely optional. + +A complete list of all possible ``Meta`` options can be found in the :doc:`model +option reference </ref/models/options>`. + +.. _model-methods: + +Model methods +============= + +Define custom methods on a model to add custom "row-level" functionality to your +objects. Whereas :class:`~django.db.models.Manager` methods are intended to do +"table-wide" things, model methods should act on a particular model instance. + +This is a valuable technique for keeping business logic in one place -- the +model. + +For example, this model has a few custom methods:: + + from django.contrib.localflavor.us.models import USStateField + + class Person(models.Model): + first_name = models.CharField(max_length=50) + last_name = models.CharField(max_length=50) + birth_date = models.DateField() + address = models.CharField(max_length=100) + city = models.CharField(max_length=50) + state = USStateField() # Yes, this is America-centric... + + def baby_boomer_status(self): + "Returns the person's baby-boomer status." + import datetime + if datetime.date(1945, 8, 1) <= self.birth_date <= datetime.date(1964, 12, 31): + return "Baby boomer" + if self.birth_date < datetime.date(1945, 8, 1): + return "Pre-boomer" + return "Post-boomer" + + def is_midwestern(self): + "Returns True if this person is from the Midwest." + return self.state in ('IL', 'WI', 'MI', 'IN', 'OH', 'IA', 'MO') + + def _get_full_name(self): + "Returns the person's full name." + return '%s %s' % (self.first_name, self.last_name) + full_name = property(_get_full_name) + +The last method in this example is a :term:`property`. `Read more about +properties`_. + +.. _Read more about properties: http://www.python.org/download/releases/2.2/descrintro/#property + +The :doc:`model instance reference </ref/models/instances>` has a complete list +of :ref:`methods automatically given to each model <model-instance-methods>`. +You can override most of these -- see `overriding predefined model methods`_, +below -- but there are a couple that you'll almost always want to define: + + :meth:`~Model.__unicode__` + A Python "magic method" that returns a unicode "representation" of any + object. This is what Python and Django will use whenever a model + instance needs to be coerced and displayed as a plain string. Most + notably, this happens when you display an object in an interactive + console or in the admin. + + You'll always want to define this method; the default isn't very helpful + at all. + + :meth:`~Model.get_absolute_url` + This tells Django how to calculate the URL for an object. Django uses + this in its admin interface, and any time it needs to figure out a URL + for an object. + + Any object that has a URL that uniquely identifies it should define this + method. + +.. _overriding-model-methods: + +Overriding predefined model methods +----------------------------------- + +There's another set of :ref:`model methods <model-instance-methods>` that +encapsulate a bunch of database behavior that you'll want to customize. In +particular you'll often want to change the way :meth:`~Model.save` and +:meth:`~Model.delete` work. + +You're free to override these methods (and any other model method) to alter +behavior. + +A classic use-case for overriding the built-in methods is if you want something +to happen whenever you save an object. For example (see +:meth:`~Model.save` for documentation of the parameters it accepts):: + + class Blog(models.Model): + name = models.CharField(max_length=100) + tagline = models.TextField() + + def save(self, *args, **kwargs): + do_something() + super(Blog, self).save(*args, **kwargs) # Call the "real" save() method. + do_something_else() + +You can also prevent saving:: + + class Blog(models.Model): + name = models.CharField(max_length=100) + tagline = models.TextField() + + def save(self, *args, **kwargs): + if self.name == "Yoko Ono's blog": + return # Yoko shall never have her own blog! + else: + super(Blog, self).save(*args, **kwargs) # Call the "real" save() method. + +It's important to remember to call the superclass method -- that's +that ``super(Blog, self).save(*args, **kwargs)`` business -- to ensure +that the object still gets saved into the database. If you forget to +call the superclass method, the default behavior won't happen and the +database won't get touched. + +It's also important that you pass through the arguments that can be +passed to the model method -- that's what the ``*args, **kwargs`` bit +does. Django will, from time to time, extend the capabilities of +built-in model methods, adding new arguments. If you use ``*args, +**kwargs`` in your method definitions, you are guaranteed that your +code will automatically support those arguments when they are added. + +Executing custom SQL +-------------------- + +Another common pattern is writing custom SQL statements in model methods and +module-level methods. For more details on using raw SQL, see the documentation +on :doc:`using raw SQL</topics/db/sql>`. + +.. _model-inheritance: + +Model inheritance +================= + +.. versionadded:: 1.0 + +Model inheritance in Django works almost identically to the way normal +class inheritance works in Python. The only decision you have to make +is whether you want the parent models to be models in their own right +(with their own database tables), or if the parents are just holders +of common information that will only be visible through the child +models. + +There are three styles of inheritance that are possible in Django. + + 1. Often, you will just want to use the parent class to hold information that + you don't want to have to type out for each child model. This class isn't + going to ever be used in isolation, so :ref:`abstract-base-classes` are + what you're after. + 2. If you're subclassing an existing model (perhaps something from another + application entirely) and want each model to have its own database table, + :ref:`multi-table-inheritance` is the way to go. + 3. Finally, if you only want to modify the Python-level behaviour of a model, + without changing the models fields in any way, you can use + :ref:`proxy-models`. + +.. _abstract-base-classes: + +Abstract base classes +--------------------- + +Abstract base classes are useful when you want to put some common +information into a number of other models. You write your base class +and put ``abstract=True`` in the :ref:`Meta <meta-options>` +class. This model will then not be used to create any database +table. Instead, when it is used as a base class for other models, its +fields will be added to those of the child class. It is an error to +have fields in the abstract base class with the same name as those in +the child (and Django will raise an exception). + +An example:: + + class CommonInfo(models.Model): + name = models.CharField(max_length=100) + age = models.PositiveIntegerField() + + class Meta: + abstract = True + + class Student(CommonInfo): + home_group = models.CharField(max_length=5) + +The ``Student`` model will have three fields: ``name``, ``age`` and +``home_group``. The ``CommonInfo`` model cannot be used as a normal Django +model, since it is an abstract base class. It does not generate a database +table or have a manager, and cannot be instantiated or saved directly. + +For many uses, this type of model inheritance will be exactly what you want. +It provides a way to factor out common information at the Python level, whilst +still only creating one database table per child model at the database level. + +``Meta`` inheritance +~~~~~~~~~~~~~~~~~~~~ + +When an abstract base class is created, Django makes any :ref:`Meta <meta-options>` +inner class you declared in the base class available as an +attribute. If a child class does not declare its own :ref:`Meta <meta-options>` +class, it will inherit the parent's :ref:`Meta <meta-options>`. If the child wants to +extend the parent's :ref:`Meta <meta-options>` class, it can subclass it. For example:: + + class CommonInfo(models.Model): + ... + class Meta: + abstract = True + ordering = ['name'] + + class Student(CommonInfo): + ... + class Meta(CommonInfo.Meta): + db_table = 'student_info' + +Django does make one adjustment to the :ref:`Meta <meta-options>` class of an abstract base +class: before installing the :ref:`Meta <meta-options>` attribute, it sets ``abstract=False``. +This means that children of abstract base classes don't automatically become +abstract classes themselves. Of course, you can make an abstract base class +that inherits from another abstract base class. You just need to remember to +explicitly set ``abstract=True`` each time. + +Some attributes won't make sense to include in the :ref:`Meta <meta-options>` class of an +abstract base class. For example, including ``db_table`` would mean that all +the child classes (the ones that don't specify their own :ref:`Meta <meta-options>`) would use +the same database table, which is almost certainly not what you want. + +.. _abstract-related-name: + +Be careful with ``related_name`` +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +If you are using the :attr:`~django.db.models.ForeignKey.related_name` attribute on a ``ForeignKey`` or +``ManyToManyField``, you must always specify a *unique* reverse name for the +field. This would normally cause a problem in abstract base classes, since the +fields on this class are included into each of the child classes, with exactly +the same values for the attributes (including :attr:`~django.db.models.ForeignKey.related_name`) each time. + +.. versionchanged:: 1.2 + +To work around this problem, when you are using :attr:`~django.db.models.ForeignKey.related_name` in an +abstract base class (only), part of the name should contain +``'%(app_label)s'`` and ``'%(class)s'``. + +- ``'%(class)s'`` is replaced by the lower-cased name of the child class + that the field is used in. +- ``'%(app_label)s'`` is replaced by the lower-cased name of the app the child + class is contained within. Each installed application name must be unique + and the model class names within each app must also be unique, therefore the + resulting name will end up being different. + +For example, given an app ``common/models.py``:: + + class Base(models.Model): + m2m = models.ManyToManyField(OtherModel, related_name="%(app_label)s_%(class)s_related") + + class Meta: + abstract = True + + class ChildA(Base): + pass + + class ChildB(Base): + pass + +Along with another app ``rare/models.py``:: + + from common.models import Base + + class ChildB(Base): + pass + +The reverse name of the ``commmon.ChildA.m2m`` field will be +``common_childa_related``, whilst the reverse name of the +``common.ChildB.m2m`` field will be ``common_childb_related``, and finally the +reverse name of the ``rare.ChildB.m2m`` field will be ``rare_childb_related``. +It is up to you how you use the ``'%(class)s'`` and ``'%(app_label)s`` portion +to construct your related name, but if you forget to use it, Django will raise +errors when you validate your models (or run :djadmin:`syncdb`). + +If you don't specify a :attr:`~django.db.models.ForeignKey.related_name` +attribute for a field in an abstract base class, the default reverse name will +be the name of the child class followed by ``'_set'``, just as it normally +would be if you'd declared the field directly on the child class. For example, +in the above code, if the :attr:`~django.db.models.ForeignKey.related_name` +attribute was omitted, the reverse name for the ``m2m`` field would be +``childa_set`` in the ``ChildA`` case and ``childb_set`` for the ``ChildB`` +field. + +.. _multi-table-inheritance: + +Multi-table inheritance +----------------------- + +The second type of model inheritance supported by Django is when each model in +the hierarchy is a model all by itself. Each model corresponds to its own +database table and can be queried and created individually. The inheritance +relationship introduces links between the child model and each of its parents +(via an automatically-created :class:`~django.db.models.fields.OneToOneField`). +For example:: + + class Place(models.Model): + name = models.CharField(max_length=50) + address = models.CharField(max_length=80) + + class Restaurant(Place): + serves_hot_dogs = models.BooleanField() + serves_pizza = models.BooleanField() + +All of the fields of ``Place`` will also be available in ``Restaurant``, +although the data will reside in a different database table. So these are both +possible:: + + >>> Place.objects.filter(name="Bob's Cafe") + >>> Restaurant.objects.filter(name="Bob's Cafe") + +If you have a ``Place`` that is also a ``Restaurant``, you can get from the +``Place`` object to the ``Restaurant`` object by using the lower-case version +of the model name:: + + >>> p = Place.objects.get(id=12) + # If p is a Restaurant object, this will give the child class: + >>> p.restaurant + <Restaurant: ...> + +However, if ``p`` in the above example was *not* a ``Restaurant`` (it had been +created directly as a ``Place`` object or was the parent of some other class), +referring to ``p.restaurant`` would raise a Restaurant.DoesNotExist exception. + +``Meta`` and multi-table inheritance +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +In the multi-table inheritance situation, it doesn't make sense for a child +class to inherit from its parent's :ref:`Meta <meta-options>` class. All the :ref:`Meta <meta-options>` options +have already been applied to the parent class and applying them again would +normally only lead to contradictory behavior (this is in contrast with the +abstract base class case, where the base class doesn't exist in its own +right). + +So a child model does not have access to its parent's :ref:`Meta +<meta-options>` class. However, there are a few limited cases where the child +inherits behavior from the parent: if the child does not specify an +:attr:`~django.db.models.Options.ordering` attribute or a +:attr:`~django.db.models.Options.get_latest_by` attribute, it will inherit +these from its parent. + +If the parent has an ordering and you don't want the child to have any natural +ordering, you can explicitly disable it:: + + class ChildModel(ParentModel): + ... + class Meta: + # Remove parent's ordering effect + ordering = [] + +Inheritance and reverse relations +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +Because multi-table inheritance uses an implicit +:class:`~django.db.models.OneToOneField` to link the child and +the parent, it's possible to move from the parent down to the child, +as in the above example. However, this uses up the name that is the +default :attr:`~django.db.models.ForeignKey.related_name` value for +:class:`~django.db.models.ForeignKey` and +:class:`~django.db.models.ManyToManyField` relations. If you +are putting those types of relations on a subclass of another model, +you **must** specify the +:attr:`~django.db.models.ForeignKey.related_name` attribute on each +such field. If you forget, Django will raise an error when you run +:djadmin:`validate` or :djadmin:`syncdb`. + +For example, using the above ``Place`` class again, let's create another +subclass with a :class:`~django.db.models.ManyToManyField`:: + + class Supplier(Place): + # Must specify related_name on all relations. + customers = models.ManyToManyField(Restaurant, related_name='provider') + + +Specifying the parent link field +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +As mentioned, Django will automatically create a +:class:`~django.db.models.OneToOneField` linking your child +class back any non-abstract parent models. If you want to control the +name of the attribute linking back to the parent, you can create your +own :class:`~django.db.models.OneToOneField` and set +:attr:`parent_link=True <django.db.models.OneToOneField.parent_link>` +to indicate that your field is the link back to the parent class. + +.. _proxy-models: + +Proxy models +------------ + +.. versionadded:: 1.1 + +When using :ref:`multi-table inheritance <multi-table-inheritance>`, a new +database table is created for each subclass of a model. This is usually the +desired behavior, since the subclass needs a place to store any additional +data fields that are not present on the base class. Sometimes, however, you +only want to change the Python behavior of a model -- perhaps to change the +default manager, or add a new method. + +This is what proxy model inheritance is for: creating a *proxy* for the +original model. You can create, delete and update instances of the proxy model +and all the data will be saved as if you were using the original (non-proxied) +model. The difference is that you can change things like the default model +ordering or the default manager in the proxy, without having to alter the +original. + +Proxy models are declared like normal models. You tell Django that it's a +proxy model by setting the :attr:`~django.db.models.Options.proxy` attribute of +the ``Meta`` class to ``True``. + +For example, suppose you want to add a method to the standard +:class:`~django.contrib.auth.models.User` model that will be used in your +templates. You can do it like this:: + + from django.contrib.auth.models import User + + class MyUser(User): + class Meta: + proxy = True + + def do_something(self): + ... + +The ``MyUser`` class operates on the same database table as its parent +:class:`~django.contrib.auth.models.User` class. In particular, any new +instances of :class:`~django.contrib.auth.models.User` will also be accessible +through ``MyUser``, and vice-versa:: + + >>> u = User.objects.create(username="foobar") + >>> MyUser.objects.get(username="foobar") + <MyUser: foobar> + +You could also use a proxy model to define a different default ordering on a +model. The standard :class:`~django.contrib.auth.models.User` model has no +ordering defined on it (intentionally; sorting is expensive and we don't want +to do it all the time when we fetch users). You might want to regularly order +by the ``username`` attribute when you use the proxy. This is easy:: + + class OrderedUser(User): + class Meta: + ordering = ["username"] + proxy = True + +Now normal :class:`~django.contrib.auth.models.User` queries will be unordered +and ``OrderedUser`` queries will be ordered by ``username``. + +QuerySets still return the model that was requested +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +There is no way to have Django return, say, a ``MyUser`` object whenever you +query for :class:`~django.contrib.auth.models.User` objects. A queryset for +``User`` objects will return those types of objects. The whole point of proxy +objects is that code relying on the original ``User`` will use those and your +own code can use the extensions you included (that no other code is relying on +anyway). It is not a way to replace the ``User`` (or any other) model +everywhere with something of your own creation. + +Base class restrictions +~~~~~~~~~~~~~~~~~~~~~~~ + +A proxy model must inherit from exactly one non-abstract model class. You +can't inherit from multiple non-abstract models as the proxy model doesn't +provide any connection between the rows in the different database tables. A +proxy model can inherit from any number of abstract model classes, providing +they do *not* define any model fields. + +Proxy models inherit any ``Meta`` options that they don't define from their +non-abstract model parent (the model they are proxying for). + +Proxy model managers +~~~~~~~~~~~~~~~~~~~~ + +If you don't specify any model managers on a proxy model, it inherits the +managers from its model parents. If you define a manager on the proxy model, +it will become the default, although any managers defined on the parent +classes will still be available. + +Continuing our example from above, you could change the default manager used +when you query the ``User`` model like this:: + + class NewManager(models.Manager): + ... + + class MyUser(User): + objects = NewManager() + + class Meta: + proxy = True + +If you wanted to add a new manager to the Proxy, without replacing the +existing default, you can use the techniques described in the :ref:`custom +manager <custom-managers-and-inheritance>` documentation: create a base class +containing the new managers and inherit that after the primary base class:: + + # Create an abstract class for the new manager. + class ExtraManagers(models.Model): + secondary = NewManager() + + class Meta: + abstract = True + + class MyUser(User, ExtraManagers): + class Meta: + proxy = True + +You probably won't need to do this very often, but, when you do, it's +possible. + +.. _proxy-vs-unmanaged-models: + +Differences between proxy inheritance and unmanaged models +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +Proxy model inheritance might look fairly similar to creating an unmanaged +model, using the :attr:`~django.db.models.Options.managed` attribute on a +model's ``Meta`` class. The two alternatives are not quite the same and it's +worth considering which one you should use. + +One difference is that you can (and, in fact, must unless you want an empty +model) specify model fields on models with ``Meta.managed=False``. You could, +with careful setting of :attr:`Meta.db_table +<django.db.models.Options.db_table>` create an unmanaged model that shadowed +an existing model and add Python methods to it. However, that would be very +repetitive and fragile as you need to keep both copies synchronized if you +make any changes. + +The other difference that is more important for proxy models, is how model +managers are handled. Proxy models are intended to behave exactly like the +model they are proxying for. So they inherit the parent model's managers, +including the default manager. In the normal multi-table model inheritance +case, children do not inherit managers from their parents as the custom +managers aren't always appropriate when extra fields are involved. The +:ref:`manager documentation <custom-managers-and-inheritance>` has more +details about this latter case. + +When these two features were implemented, attempts were made to squash them +into a single option. It turned out that interactions with inheritance, in +general, and managers, in particular, made the API very complicated and +potentially difficult to understand and use. It turned out that two options +were needed in any case, so the current separation arose. + +So, the general rules are: + + 1. If you are mirroring an existing model or database table and don't want + all the original database table columns, use ``Meta.managed=False``. + That option is normally useful for modeling database views and tables + not under the control of Django. + 2. If you are wanting to change the Python-only behavior of a model, but + keep all the same fields as in the original, use ``Meta.proxy=True``. + This sets things up so that the proxy model is an exact copy of the + storage structure of the original model when data is saved. + +Multiple inheritance +-------------------- + +Just as with Python's subclassing, it's possible for a Django model to inherit +from multiple parent models. Keep in mind that normal Python name resolution +rules apply. The first base class that a particular name (e.g. :ref:`Meta +<meta-options>`) appears in will be the one that is used; for example, this +means that if multiple parents contain a :ref:`Meta <meta-options>` class, +only the first one is going to be used, and all others will be ignored. + +Generally, you won't need to inherit from multiple parents. The main use-case +where this is useful is for "mix-in" classes: adding a particular extra +field or method to every class that inherits the mix-in. Try to keep your +inheritance hierarchies as simple and straightforward as possible so that you +won't have to struggle to work out where a particular piece of information is +coming from. + +Field name "hiding" is not permitted +------------------------------------- + +In normal Python class inheritance, it is permissible for a child class to +override any attribute from the parent class. In Django, this is not permitted +for attributes that are :class:`~django.db.models.fields.Field` instances (at +least, not at the moment). If a base class has a field called ``author``, you +cannot create another model field called ``author`` in any class that inherits +from that base class. + +Overriding fields in a parent model leads to difficulties in areas such as +initialising new instances (specifying which field is being initialized in +``Model.__init__``) and serialization. These are features which normal Python +class inheritance doesn't have to deal with in quite the same way, so the +difference between Django model inheritance and Python class inheritance isn't +arbitrary. + +This restriction only applies to attributes which are +:class:`~django.db.models.fields.Field` instances. Normal Python attributes +can be overridden if you wish. It also only applies to the name of the +attribute as Python sees it: if you are manually specifying the database +column name, you can have the same column name appearing in both a child and +an ancestor model for multi-table inheritance (they are columns in two +different database tables). + +Django will raise a :exc:`~django.core.exceptions.FieldError` if you override +any model field in any ancestor model. |