123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611 |
- ======
- Models
- ======
- .. module:: django.db.models
- A model is the single, definitive source of information 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`.
- 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" bigint NOT NULL PRIMARY KEY GENERATED BY DEFAULT AS IDENTITY,
- "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
- ``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 = [
- # ...
- "myapp",
- # ...
- ]
- When you add new apps to :setting:`INSTALLED_APPS`, be sure to run
- :djadmin:`manage.py migrate <migrate>`, optionally making migrations
- for them first with :djadmin:`manage.py makemigrations <makemigrations>`.
- 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. Be careful not to choose field names that conflict with the
- :doc:`models API </ref/models/instances>` like ``clean``, ``save``, or
- ``delete``.
- Example::
- from django.db import models
- 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, on_delete=models.CASCADE)
- 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 column type, which tells the database what kind of data to store (e.g.
- ``INTEGER``, ``VARCHAR``, ``TEXT``).
- * The default HTML :doc:`widget </ref/forms/widgets>` to use when rendering a form
- field (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>`, form validation will
- allow entry of an empty value. If a field has :attr:`blank=False
- <Field.blank>`, the field will be required.
- :attr:`~Field.choices`
- A :term:`sequence` of 2-value tuples, a :term:`mapping`, an
- :ref:`enumeration type <field-choices-enum-types>`, or a callable (that
- expects no arguments and returns any of the previous formats), to use as
- choices for this field. If this is given, the default form widget will be 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 = [
- ("FR", "Freshman"),
- ("SO", "Sophomore"),
- ("JR", "Junior"),
- ("SR", "Senior"),
- ("GR", "Graduate"),
- ]
- .. note::
- A new migration is created each time the order of ``choices`` changes.
- The first element in each tuple is the value that will be stored in the
- database. The second element is displayed by the field's form widget.
- Given a model instance, the display value for a field with ``choices`` can
- be accessed using the :meth:`~django.db.models.Model.get_FOO_display`
- method. For example::
- from django.db import models
- class Person(models.Model):
- SHIRT_SIZES = {
- "S": "Small",
- "M": "Medium",
- "L": "Large",
- }
- name = models.CharField(max_length=60)
- shirt_size = models.CharField(max_length=1, choices=SHIRT_SIZES)
- .. code-block:: pycon
- >>> p = Person(name="Fred Flintstone", shirt_size="L")
- >>> p.save()
- >>> p.shirt_size
- 'L'
- >>> p.get_shirt_size_display()
- 'Large'
- You can also use enumeration classes to define ``choices`` in a concise
- way::
- from django.db import models
- class Runner(models.Model):
- MedalType = models.TextChoices("MedalType", "GOLD SILVER BRONZE")
- name = models.CharField(max_length=60)
- medal = models.CharField(blank=True, choices=MedalType, max_length=10)
- Further examples are available in the :ref:`model field reference
- <field-choices>`.
- :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.db_default`
- The database-computed default value for the field. This can be a literal
- value or a database function.
- If both ``db_default`` and :attr:`Field.default` are set, ``default`` will
- take precedence when creating instances in Python code. ``db_default`` will
- still be set at the database level and will be used when inserting rows
- outside of the ORM or when adding a new field in a migration.
- :attr:`~Field.help_text`
- Extra "help" text to be displayed with the form widget. It's useful for
- documentation even if your field isn't used on a 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`.
- The primary key field is read-only. If you change the value of the primary
- key on an existing object and then save it, a new object will be created
- alongside the old one. For example::
- from django.db import models
- class Fruit(models.Model):
- name = models.CharField(max_length=100, primary_key=True)
- .. code-block:: pycon
- >>> fruit = Fruit.objects.create(name="Apple")
- >>> fruit.name = "Pear"
- >>> fruit.save()
- >>> Fruit.objects.values_list("name", flat=True)
- <QuerySet ['Apple', 'Pear']>
- :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 an auto-incrementing primary key with the
- type specified per app in :attr:`AppConfig.default_auto_field
- <django.apps.AppConfig.default_auto_field>` or globally in the
- :setting:`DEFAULT_AUTO_FIELD` setting. For example::
- id = models.BigAutoField(primary_key=True)
- If you'd like to specify a custom primary key, 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>` (either explicitly declared or automatically added).
- .. _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,
- on_delete=models.CASCADE,
- verbose_name="the related poll",
- )
- sites = models.ManyToManyField(Site, verbose_name="list of sites")
- place = models.OneToOneField(
- Place,
- on_delete=models.CASCADE,
- 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::
- from django.db import models
- class Manufacturer(models.Model):
- # ...
- pass
- class Car(models.Model):
- manufacturer = models.ForeignKey(Manufacturer, on_delete=models.CASCADE)
- # ...
- 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 call the field whatever you
- want. For example::
- class Car(models.Model):
- company_that_makes_it = models.ForeignKey(
- Manufacturer,
- on_delete=models.CASCADE,
- )
- # ...
- .. seealso::
- :class:`~django.db.models.ForeignKey` fields 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.
- For details on accessing backwards-related objects, see the
- :ref:`Following relationships backward example <backwards-related-objects>`.
- For sample code, see the :doc:`Many-to-one relationship model example
- </topics/db/examples/many_to_one>`.
- 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::
- from django.db import models
- class Topping(models.Model):
- # ...
- pass
- 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>`.
- 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 has the
- :class:`~django.db.models.ManyToManyField`, but you should only put it in one
- of the models -- not both.
- Generally, :class:`~django.db.models.ManyToManyField` instances should go in
- the object that's going to be edited on a form. 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`` form would let users select the toppings.
- .. seealso::
- See the :doc:`Many-to-many relationship model example
- </topics/db/examples/many_to_many>` for a full example.
- :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
- ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
- When you're only dealing with 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::
- from django.db import models
- class Person(models.Model):
- name = models.CharField(max_length=128)
- def __str__(self):
- return self.name
- class Group(models.Model):
- name = models.CharField(max_length=128)
- members = models.ManyToManyField(Person, through="Membership")
- def __str__(self):
- return self.name
- class Membership(models.Model):
- person = models.ForeignKey(Person, on_delete=models.CASCADE)
- group = models.ForeignKey(Group, on_delete=models.CASCADE)
- 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 many-to-many relationship. 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 source model (this would be ``Group`` in our example), or you must
- explicitly specify the foreign keys Django should use for the relationship
- using :attr:`ManyToManyField.through_fields <ManyToManyField.through_fields>`.
- If you have more than one foreign key and ``through_fields`` is not
- specified, a validation error will be raised. A similar restriction applies
- to the foreign key to the target model (this would be ``Person`` in our
- example).
- * For a model which has a many-to-many relationship to itself through an
- intermediary model, two foreign keys to the same model are permitted, but
- they will be treated as the two (different) sides of the many-to-many
- relationship. If there are *more* than two foreign keys though, you
- must also specify ``through_fields`` as above, or a validation error
- will be raised.
- 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:
- .. code-block:: pycon
- >>> 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()
- <QuerySet [<Person: Ringo Starr>]>
- >>> ringo.group_set.all()
- <QuerySet [<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()
- <QuerySet [<Person: Ringo Starr>, <Person: Paul McCartney>]>
- You can also use :meth:`~django.db.models.fields.related.RelatedManager.add`,
- :meth:`~django.db.models.fields.related.RelatedManager.create`, or
- :meth:`~django.db.models.fields.related.RelatedManager.set` to create
- relationships, as long as you specify ``through_defaults`` for any required
- fields:
- .. code-block:: pycon
- >>> beatles.members.add(john, through_defaults={"date_joined": date(1960, 8, 1)})
- >>> beatles.members.create(
- ... name="George Harrison", through_defaults={"date_joined": date(1960, 8, 1)}
- ... )
- >>> beatles.members.set(
- ... [john, paul, ringo, george], through_defaults={"date_joined": date(1960, 8, 1)}
- ... )
- You may prefer to create instances of the intermediate model directly.
- If the custom through table defined by the intermediate model does not enforce
- uniqueness on the ``(model1, model2)`` pair, allowing multiple values, the
- :meth:`~django.db.models.fields.related.RelatedManager.remove` call will
- remove all intermediate model instances:
- .. code-block:: pycon
- >>> Membership.objects.create(
- ... person=ringo,
- ... group=beatles,
- ... date_joined=date(1968, 9, 4),
- ... invite_reason="You've been gone for a month and we miss you.",
- ... )
- >>> beatles.members.all()
- <QuerySet [<Person: Ringo Starr>, <Person: Paul McCartney>, <Person: Ringo Starr>]>
- >>> # This deletes both of the intermediate model instances for Ringo Starr
- >>> beatles.members.remove(ringo)
- >>> beatles.members.all()
- <QuerySet [<Person: Paul McCartney>]>
- The :meth:`~django.db.models.fields.related.RelatedManager.clear`
- method can be used to remove all many-to-many relationships for an instance:
- .. code-block:: pycon
- >>> # Beatles have broken up
- >>> beatles.members.clear()
- >>> # Note that this deletes the intermediate model instances
- >>> Membership.objects.all()
- <QuerySet []>
- Once you have established the many-to-many relationships, 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:
- .. code-block:: pycon
- # Find all the groups with a member whose name starts with 'Paul'
- >>> Group.objects.filter(members__name__startswith="Paul")
- <QuerySet [<Group: The Beatles>]>
- As you are using an intermediate model, you can also query on its attributes:
- .. code-block:: pycon
- # 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)
- ... )
- <QuerySet [<Person: Ringo Starr]>
- If you need to access a membership's information you may do so by directly
- querying the ``Membership`` model:
- .. code-block:: pycon
- >>> ringos_membership = Membership.objects.get(group=beatles, person=ringo)
- >>> ringos_membership.date_joined
- datetime.date(1962, 8, 16)
- >>> ringos_membership.invite_reason
- 'Needed a new drummer.'
- Another way to access the same information is by querying the
- :ref:`many-to-many reverse relationship<m2m-reverse-relationships>` from a
- ``Person`` object:
- .. code-block:: pycon
- >>> ringos_membership = ringo.membership_set.get(group=beatles)
- >>> ringos_membership.date_joined
- datetime.date(1962, 8, 16)
- >>> ringos_membership.invite_reason
- 'Needed a new drummer.'
- 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.
- .. seealso::
- See the :doc:`One-to-one relationship model example
- </topics/db/examples/one_to_one>` for a full example.
- :class:`~django.db.models.OneToOneField` fields also accept an optional
- :attr:`~django.db.models.OneToOneField.parent_link` argument.
- :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 file where your model is defined. Then,
- refer to the other model class wherever needed. For example::
- from django.db import models
- from geography.models import ZipCode
- class Restaurant(models.Model):
- # ...
- zip_code = models.ForeignKey(
- ZipCode,
- on_delete=models.SET_NULL,
- blank=True,
- null=True,
- )
- Field name restrictions
- -----------------------
- Django places some restrictions on model field names:
- #. A field name cannot be a Python reserved word, because that would result
- in a Python syntax error. For example:
- .. code-block:: text
- class Example(models.Model):
- pass = models.IntegerField() # 'pass' is a reserved word!
- #. 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!
- #. A field name cannot end with an underscore, for similar reasons.
- #. A field name cannot be ``check``, as this would override the check
- framework's ``Model.check()`` method.
- 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
- ------------------
- 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::
- from django.db import models
- 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-attributes:
- Model attributes
- ================
- ``objects``
- The most important attribute of a model is the
- :class:`~django.db.models.Manager`. It's the interface through which
- database query operations are provided to Django models and is used to
- :ref:`retrieve the instances <retrieving-objects>` from the database. If no
- custom ``Manager`` is defined, the default name is
- :attr:`~django.db.models.Model.objects`. Managers are only accessible via
- model classes, not the model instances.
- .. _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.db import models
- class Person(models.Model):
- first_name = models.CharField(max_length=50)
- last_name = models.CharField(max_length=50)
- birth_date = models.DateField()
- def baby_boomer_status(self):
- "Returns the person's baby-boomer status."
- import datetime
- if self.birth_date < datetime.date(1945, 8, 1):
- return "Pre-boomer"
- elif self.birth_date < datetime.date(1965, 1, 1):
- return "Baby boomer"
- else:
- return "Post-boomer"
- @property
- def full_name(self):
- "Returns the person's full name."
- return f"{self.first_name} {self.last_name}"
- The last method in this example is a :term:`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.__str__`
- A Python "magic method" that returns a string 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)::
- from django.db import models
- class Blog(models.Model):
- name = models.CharField(max_length=100)
- tagline = models.TextField()
- def save(self, **kwargs):
- do_something()
- super().save(**kwargs) # Call the "real" save() method.
- do_something_else()
- You can also prevent saving::
- from django.db import models
- class Blog(models.Model):
- name = models.CharField(max_length=100)
- tagline = models.TextField()
- def save(self, **kwargs):
- if self.name == "Yoko Ono's blog":
- return # Yoko shall never have her own blog!
- else:
- super().save(**kwargs) # Call the "real" save() method.
- It's important to remember to call the superclass method -- that's
- that ``super().save(**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 ``**kwargs`` bit does. Django
- will, from time to time, extend the capabilities of built-in model methods,
- adding new keyword arguments. If you use ``**kwargs`` in your method
- definitions, you are guaranteed that your code will automatically support those
- arguments when they are added.
- If you wish to update a field value in the :meth:`~Model.save` method, you may
- also want to have this field added to the ``update_fields`` keyword argument.
- This will ensure the field is saved when ``update_fields`` is specified. For
- example::
- from django.db import models
- from django.utils.text import slugify
- class Blog(models.Model):
- name = models.CharField(max_length=100)
- slug = models.TextField()
- def save(self, **kwargs):
- self.slug = slugify(self.name)
- if (
- update_fields := kwargs.get("update_fields")
- ) is not None and "name" in update_fields:
- kwargs["update_fields"] = {"slug"}.union(update_fields)
- super().save(**kwargs)
- See :ref:`ref-models-update-fields` for more details.
- .. admonition:: Overridden model methods are not called on bulk operations
- Note that the :meth:`~Model.delete()` method for an object is not
- necessarily called when :ref:`deleting objects in bulk using a
- QuerySet <topics-db-queries-delete>` or as a result of a :attr:`cascading
- delete <django.db.models.ForeignKey.on_delete>`. To ensure customized
- delete logic gets executed, you can use
- :data:`~django.db.models.signals.pre_delete` and/or
- :data:`~django.db.models.signals.post_delete` signals.
- Unfortunately, there isn't a workaround when
- :meth:`creating<django.db.models.query.QuerySet.bulk_create>` or
- :meth:`updating<django.db.models.query.QuerySet.update>` objects in bulk,
- since none of :meth:`~Model.save()`,
- :data:`~django.db.models.signals.pre_save`, and
- :data:`~django.db.models.signals.post_save` are called.
- 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
- =================
- Model inheritance in Django works almost identically to the way normal
- class inheritance works in Python, but the basics at the beginning of the page
- should still be followed. That means the base class should subclass
- :class:`django.db.models.Model`.
- 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 behavior 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.
- An example::
- from django.db import models
- 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.
- Fields inherited from abstract base classes can be overridden with another
- field or value, or be removed with ``None``.
- 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, while
- 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::
- from django.db import models
- 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. To make
- an abstract base class that inherits from another abstract base class, you need
- to explicitly set ``abstract=True`` on the child.
- 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.
- Due to the way Python inheritance works, if a child class inherits from
- multiple abstract base classes, only the :ref:`Meta <meta-options>` options
- from the first listed class will be inherited by default. To inherit :ref:`Meta
- <meta-options>` options from multiple abstract base classes, you must
- explicitly declare the :ref:`Meta <meta-options>` inheritance. For example::
- from django.db import models
- class CommonInfo(models.Model):
- name = models.CharField(max_length=100)
- age = models.PositiveIntegerField()
- class Meta:
- abstract = True
- ordering = ["name"]
- class Unmanaged(models.Model):
- class Meta:
- abstract = True
- managed = False
- class Student(CommonInfo, Unmanaged):
- home_group = models.CharField(max_length=5)
- class Meta(CommonInfo.Meta, Unmanaged.Meta):
- pass
- .. _abstract-related-name:
- Be careful with ``related_name`` and ``related_query_name``
- ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
- If you are using :attr:`~django.db.models.ForeignKey.related_name` or
- :attr:`~django.db.models.ForeignKey.related_query_name` on a ``ForeignKey`` or
- ``ManyToManyField``, you must always specify a *unique* reverse name and query
- 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` and
- :attr:`~django.db.models.ForeignKey.related_query_name`) each time.
- To work around this problem, when you are using
- :attr:`~django.db.models.ForeignKey.related_name` or
- :attr:`~django.db.models.ForeignKey.related_query_name` in an abstract base
- class (only), part of the value should contain ``'%(app_label)s'`` and
- ``'%(class)s'``.
- - ``'%(class)s'`` is replaced by the lowercased name of the child class that
- the field is used in.
- - ``'%(app_label)s'`` is replaced by the lowercased 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``::
- from django.db import models
- class Base(models.Model):
- m2m = models.ManyToManyField(
- OtherModel,
- related_name="%(app_label)s_%(class)s_related",
- related_query_name="%(app_label)s_%(class)ss",
- )
- 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 ``common.ChildA.m2m`` field will be
- ``common_childa_related`` and the reverse query name will be ``common_childas``.
- The reverse name of the ``common.ChildB.m2m`` field will be
- ``common_childb_related`` and the reverse query name will be
- ``common_childbs``. Finally, the reverse name of the ``rare.ChildB.m2m`` field
- will be ``rare_childb_related`` and the reverse query name will be
- ``rare_childbs``. It's up to you how you use the ``'%(class)s'`` and
- ``'%(app_label)s'`` portion to construct your related name or related query name
- but if you forget to use it, Django will raise errors when you perform system
- checks (or run :djadmin:`migrate`).
- 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.OneToOneField`).
- For example::
- from django.db import models
- class Place(models.Model):
- name = models.CharField(max_length=50)
- address = models.CharField(max_length=80)
- class Restaurant(Place):
- serves_hot_dogs = models.BooleanField(default=False)
- serves_pizza = models.BooleanField(default=False)
- 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:
- .. code-block:: pycon
- >>> 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 lowercase version of
- the model name:
- .. code-block:: pycon
- >>> 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.
- The automatically-created :class:`~django.db.models.OneToOneField` on
- ``Restaurant`` that links it to ``Place`` looks like this::
- place_ptr = models.OneToOneField(
- Place,
- on_delete=models.CASCADE,
- parent_link=True,
- primary_key=True,
- )
- You can override that field by declaring your own
- :class:`~django.db.models.OneToOneField` with :attr:`parent_link=True
- <django.db.models.OneToOneField.parent_link>` on ``Restaurant``.
- .. _meta-and-multi-table-inheritance:
- ``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 the parent model, you
- **must** specify the :attr:`~django.db.models.ForeignKey.related_name`
- attribute on each such field. If you forget, Django will raise a validation
- error.
- For example, using the above ``Place`` class again, let's create another
- subclass with a :class:`~django.db.models.ManyToManyField`::
- class Supplier(Place):
- customers = models.ManyToManyField(Place)
- This results in the error:
- .. code-block:: pytb
- Reverse query name for 'Supplier.customers' clashes with reverse query
- name for 'Supplier.place_ptr'.
- HINT: Add or change a related_name argument to the definition for
- 'Supplier.customers' or 'Supplier.place_ptr'.
- Adding ``related_name`` to the ``customers`` field as follows would resolve the
- error: ``models.ManyToManyField(Place, 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 to 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
- ------------
- 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 ``Person`` model. You can do it like this::
- from django.db import models
- class Person(models.Model):
- first_name = models.CharField(max_length=30)
- last_name = models.CharField(max_length=30)
- class MyPerson(Person):
- class Meta:
- proxy = True
- def do_something(self):
- # ...
- pass
- The ``MyPerson`` class operates on the same database table as its parent
- ``Person`` class. In particular, any new instances of ``Person`` will also be
- accessible through ``MyPerson``, and vice-versa:
- .. code-block:: pycon
- >>> p = Person.objects.create(first_name="foobar")
- >>> MyPerson.objects.get(first_name="foobar")
- <MyPerson: foobar>
- You could also use a proxy model to define a different default ordering on
- a model. You might not always want to order the ``Person`` model, but regularly
- order by the ``last_name`` attribute when you use the proxy::
- class OrderedPerson(Person):
- class Meta:
- ordering = ["last_name"]
- proxy = True
- Now normal ``Person`` queries will be unordered
- and ``OrderedPerson`` queries will be ordered by ``last_name``.
- Proxy models inherit ``Meta`` attributes :ref:`in the same way as regular
- models <meta-and-multi-table-inheritance>`.
- ``QuerySet``\s still return the model that was requested
- ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
- There is no way to have Django return, say, a ``MyPerson`` object whenever you
- query for ``Person`` objects. A queryset for ``Person`` objects will return
- those types of objects. The whole point of proxy objects is that code relying
- on the original ``Person`` 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 ``Person`` (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. A proxy model may also inherit from any
- number of proxy models that share a common non-abstract parent class.
- 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 ``Person`` model like this::
- from django.db import models
- class NewManager(models.Manager):
- # ...
- pass
- class MyPerson(Person):
- 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 MyPerson(Person, 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.
- With careful setting of :attr:`Meta.db_table
- <django.db.models.Options.db_table>` you could create an unmanaged model that
- shadows an existing model and adds 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.
- On the other hand, proxy models are intended to behave exactly like the model
- they are proxying for. They are always in sync with the parent model since they
- directly inherit its fields and managers.
- The general rules are:
- #. 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.
- #. 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.
- .. _model-multiple-inheritance-topic:
- 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.
- Note that inheriting from multiple models that have a common ``id`` primary
- key field will raise an error. To properly use multiple inheritance, you can
- use an explicit :class:`~django.db.models.AutoField` in the base models::
- class Article(models.Model):
- article_id = models.AutoField(primary_key=True)
- ...
- class Book(models.Model):
- book_id = models.AutoField(primary_key=True)
- ...
- class BookReview(Book, Article):
- pass
- Or use a common ancestor to hold the :class:`~django.db.models.AutoField`. This
- requires using an explicit :class:`~django.db.models.OneToOneField` from each
- parent model to the common ancestor to avoid a clash between the fields that
- are automatically generated and inherited by the child::
- class Piece(models.Model):
- pass
- class Article(Piece):
- article_piece = models.OneToOneField(
- Piece, on_delete=models.CASCADE, parent_link=True
- )
- ...
- class Book(Piece):
- book_piece = models.OneToOneField(Piece, on_delete=models.CASCADE, parent_link=True)
- ...
- class BookReview(Book, Article):
- pass
- 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 isn't usually
- permitted for model fields. If a non-abstract model base class has a field
- called ``author``, you can't create another model field or define
- an attribute called ``author`` in any class that inherits from that base class.
- This restriction doesn't apply to model fields inherited from an abstract
- model. Such fields may be overridden with another field or value, or be removed
- by setting ``field_name = None``.
- .. warning::
- Model managers are inherited from abstract base classes. Overriding an
- inherited field which is referenced by an inherited
- :class:`~django.db.models.Manager` may cause subtle bugs. See :ref:`custom
- managers and model inheritance <custom-managers-and-inheritance>`.
- .. note::
- Some fields define extra attributes on the model, e.g. a
- :class:`~django.db.models.ForeignKey` defines an extra attribute with
- ``_id`` appended to the field name, as well as ``related_name`` and
- ``related_query_name`` on the foreign model.
- These extra attributes cannot be overridden unless the field that defines
- it is changed or removed so that it no longer defines the extra attribute.
- Overriding fields in a parent model leads to difficulties in areas such as
- initializing 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.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.
- Note that because of the way fields are resolved during class definition, model
- fields inherited from multiple abstract parent models are resolved in a strict
- depth-first order. This contrasts with standard Python MRO, which is resolved
- breadth-first in cases of diamond shaped inheritance. This difference only
- affects complex model hierarchies, which (as per the advice above) you should
- try to avoid.
- Organizing models in a package
- ==============================
- The :djadmin:`manage.py startapp <startapp>` command creates an application
- structure that includes a ``models.py`` file. If you have many models,
- organizing them in separate files may be useful.
- To do so, create a ``models`` package. Remove ``models.py`` and create a
- ``myapp/models/`` directory with an ``__init__.py`` file and the files to
- store your models. You must import the models in the ``__init__.py`` file.
- For example, if you had ``organic.py`` and ``synthetic.py`` in the ``models``
- directory:
- .. code-block:: python
- :caption: ``myapp/models/__init__.py``
- from .organic import Person
- from .synthetic import Robot
- Explicitly importing each model rather than using ``from .models import *``
- has the advantages of not cluttering the namespace, making code more readable,
- and keeping code analysis tools useful.
- .. seealso::
- :doc:`The Models Reference </ref/models/index>`
- Covers all the model related APIs including model fields, related
- objects, and ``QuerySet``.
|