mirror of
https://github.com/django/django.git
synced 2025-08-04 02:48:35 +00:00
Merged the queryset-refactor branch into trunk.
This is a big internal change, but mostly backwards compatible with existing code. Also adds a couple of new features. Fixed #245, #1050, #1656, #1801, #2076, #2091, #2150, #2253, #2306, #2400, #2430, #2482, #2496, #2676, #2737, #2874, #2902, #2939, #3037, #3141, #3288, #3440, #3592, #3739, #4088, #4260, #4289, #4306, #4358, #4464, #4510, #4858, #5012, #5020, #5261, #5295, #5321, #5324, #5325, #5555, #5707, #5796, #5817, #5987, #6018, #6074, #6088, #6154, #6177, #6180, #6203, #6658 git-svn-id: http://code.djangoproject.com/svn/django/trunk@7477 bcc190cf-cafb-0310-a4f2-bffc1f526a37
This commit is contained in:
parent
c91a30f00f
commit
9c52d56f6f
57 changed files with 5717 additions and 1739 deletions
|
@ -886,6 +886,10 @@ relationship should work. All are optional:
|
|||
`related objects documentation`_ for a full
|
||||
explanation and example.
|
||||
|
||||
If using this in an `abstract base class`_, be
|
||||
sure to read the `extra notes`_ in that section
|
||||
about ``related_name``.
|
||||
|
||||
``to_field`` The field on the related object that the relation
|
||||
is to. By default, Django uses the primary key of
|
||||
the related object.
|
||||
|
@ -893,6 +897,8 @@ relationship should work. All are optional:
|
|||
|
||||
.. _`Database API reference`: ../db-api/
|
||||
.. _related objects documentation: ../db-api/#related-objects
|
||||
.. _abstract base class: `Abstract base classes`_
|
||||
.. _extra notes: `Be careful with related_name`_
|
||||
|
||||
Many-to-many relationships
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
@ -988,9 +994,6 @@ the relationship should work. All are optional:
|
|||
One-to-one relationships
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
The semantics of one-to-one relationships will be changing soon, so we don't
|
||||
recommend you use them. If that doesn't scare you away, keep reading.
|
||||
|
||||
To define a one-to-one relationship, use ``OneToOneField``. You use it just
|
||||
like any other ``Field`` type: by including it as a class attribute of your
|
||||
model.
|
||||
|
@ -1012,9 +1015,26 @@ As with ``ForeignKey``, a relationship to self can be defined by using the
|
|||
string ``"self"`` instead of the model name; references to as-yet undefined
|
||||
models can be made by using a string containing the model name.
|
||||
|
||||
This ``OneToOneField`` will actually replace the primary key ``id`` field
|
||||
(since one-to-one relations share the same primary key), and will be displayed
|
||||
as a read-only field when you edit an object in the admin interface:
|
||||
Finally, ``OneToOneField`` takes the following extra option:
|
||||
|
||||
======================= ============================================================
|
||||
Argument Description
|
||||
======================= ============================================================
|
||||
``parent_link`` When ``True`` and used in a model inherited from
|
||||
another model, indicates that this field should
|
||||
be used as the link from the child back to the
|
||||
parent. See `Model inheritance`_ for more
|
||||
details.
|
||||
|
||||
**New in Django development version**
|
||||
|
||||
======================= ============================================================
|
||||
|
||||
**New in Django development version:** ``OneToOneField`` classes used to
|
||||
automatically become the primary key on a model. This is no longer true,
|
||||
although you can manually pass in the ``primary_key`` attribute if you like.
|
||||
Thus, it's now possible to have multiple fields of type ``OneToOneField`` on a
|
||||
single model.
|
||||
|
||||
See the `One-to-one relationship model example`_ for a full example.
|
||||
|
||||
|
@ -1048,6 +1068,14 @@ Model metadata is "anything that's not a field", such as ordering options, etc.
|
|||
Here's a list of all possible ``Meta`` options. No options are required. Adding
|
||||
``class Meta`` to a model is completely optional.
|
||||
|
||||
``abstract``
|
||||
------------
|
||||
|
||||
**New in Django development version**
|
||||
|
||||
When set to ``True``, denotes this model as an abstract base class. See
|
||||
`Abstract base classes`_ for more details. Defaults to ``False``.
|
||||
|
||||
``db_table``
|
||||
------------
|
||||
|
||||
|
@ -1155,6 +1183,10 @@ together. It's used in the Django admin and is enforced at the database
|
|||
level (i.e., the appropriate ``UNIQUE`` statements are included in the
|
||||
``CREATE TABLE`` statement).
|
||||
|
||||
All the fields specified in ``unique_together`` must be part of the current
|
||||
model. If you are using `model inheritance`_, you cannot refer to fields from
|
||||
any parent classes in ``unique_together``.
|
||||
|
||||
**New in Django development version**
|
||||
|
||||
For convenience, unique_together can be a single list when dealing
|
||||
|
@ -2041,6 +2073,238 @@ You can also prevent saving::
|
|||
|
||||
.. _database API docs: ../db-api/
|
||||
|
||||
Model inheritance
|
||||
=================
|
||||
|
||||
**New in Django development version**
|
||||
|
||||
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.
|
||||
|
||||
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 `abstract base classes`_ are what you're after. However, if you're subclassing an existing model (perhaps something from another application entirely), or want each model to have its own database table, `multi-table inheritance`_ is the way to go.
|
||||
|
||||
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 ``Meta`` 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 or anything like that.
|
||||
|
||||
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 ``Meta`` inner class
|
||||
you declared on the base class available as an attribute. If a child class
|
||||
does not declared its own ``Meta`` class, it will inherit the parent's
|
||||
``Meta``. If the child wants to extend the parent's ``Meta`` 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 ``Meta`` class of an abstract base
|
||||
class: before installing the ``Meta`` 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 ``Meta`` 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 ``Meta``) would use
|
||||
the same database table, which is almost certainly not what you want.
|
||||
|
||||
Be careful with ``related_name``
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
If you are using the ``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 ``related_name``) each time.
|
||||
|
||||
To work around this problem, when you are using ``related_name`` in an
|
||||
abstract base class (only), part of the name should be the string
|
||||
``'%(class)s'``. This is replaced by the lower-cased name of the child class
|
||||
that the field is used in. Since each class has a different name, each related
|
||||
name will end up being different. For example::
|
||||
|
||||
class Base(models.Model):
|
||||
m2m = models.ManyToMany(OtherModel, related_name="%(class)s_related")
|
||||
|
||||
class Meta:
|
||||
abstract = True
|
||||
|
||||
class ChildA(Base):
|
||||
pass
|
||||
|
||||
class ChildB(Base):
|
||||
pass
|
||||
|
||||
The reverse name of the ``ChildA.m2m`` field will be ``childa_related``,
|
||||
whilst the reverse name of the ``ChildB.m2m`` field will be
|
||||
``childb_related``. It is up to you how you use the ``'%(class)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 ``syncdb``).
|
||||
|
||||
If you don't specify a ``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 ``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
|
||||
-----------------------
|
||||
|
||||
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 indvidually. The inheritance
|
||||
relationship introduces links between the child model and each of its parents
|
||||
(via an automatically created ``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.filter(name="Bob's Cafe")
|
||||
# If Bob's Cafe 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 give an error.
|
||||
|
||||
``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 ``Meta`` class. All the ``Meta`` options
|
||||
have already been applied to the parent class and applying them again would
|
||||
normally only lead to contradictory behaviour (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 ``Meta`` class. However,
|
||||
there are a few limited cases where the child inherits behaviour from the
|
||||
parent: if the child does not specify an ``ordering`` attribute or a
|
||||
``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 explicity set it to be empty::
|
||||
|
||||
class ChildModel(ParentModel):
|
||||
...
|
||||
class Meta:
|
||||
# Remove parent's ordering effect
|
||||
ordering = []
|
||||
|
||||
Inheritance and reverse relations
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
Because multi-table inheritance uses an implicit ``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
|
||||
``related_name`` value for ``ForeignKey`` and ``ManyToManyField`` relations.
|
||||
If you are putting those type of relations on a subclass of another model, you
|
||||
**must** specify the ``related_name`` attribute on each such field. If you
|
||||
forget, Django will raise an error when you run ``manage.py validate`` or try
|
||||
to syncdb.
|
||||
|
||||
For example, using the above ``Place`` class again, let's create another
|
||||
subclass with a ``ManyToManyField``::
|
||||
|
||||
class Supplier(Place):
|
||||
# Must specify related_name on all relations.
|
||||
customers = models.ManyToManyField(Restaurant,
|
||||
related_name='provider')
|
||||
|
||||
For more information about reverse relations, refer to the `Database API
|
||||
reference`_ . For now, just remember to run ``manage.py validate`` when
|
||||
you're writing your models and pay attention to the error messages.
|
||||
|
||||
Specifying the parent link field
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
As mentioned, Django will automatically create a ``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
|
||||
link field and pass it ``parent_link=True``. For example, to explicitly
|
||||
specify the field that will link ``Supplier`` to ``Place`` in the above
|
||||
example, you could write::
|
||||
|
||||
class Supplier(Place):
|
||||
parent = models.OneToOneField(Place, parent_link=True)
|
||||
...
|
||||
|
||||
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 appears in (e.g.
|
||||
``Meta``) will be the one that is used. We stop searching once we find the
|
||||
name once. This means that if multiple parents contain a ``Meta`` class, only
|
||||
the first one is going to be used. 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.
|
||||
|
||||
Models across files
|
||||
===================
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue