Add missing imports and models to the examples in the the model layer documentation

This commit is contained in:
Marc Egli 2013-05-18 12:12:26 +02:00
parent d5ce2ff5e4
commit e4591debd1
9 changed files with 122 additions and 33 deletions

View File

@ -97,6 +97,8 @@ second element is the human-readable name. For example::
Generally, it's best to define choices inside a model class, and to Generally, it's best to define choices inside a model class, and to
define a suitably-named constant for each value:: define a suitably-named constant for each value::
from django.db import models
class Student(models.Model): class Student(models.Model):
FRESHMAN = 'FR' FRESHMAN = 'FR'
SOPHOMORE = 'SO' SOPHOMORE = 'SO'
@ -994,12 +996,15 @@ relationship with itself -- use ``models.ForeignKey('self')``.
If you need to create a relationship on a model that has not yet been defined, If you need to create a relationship on a model that has not yet been defined,
you can use the name of the model, rather than the model object itself:: you can use the name of the model, rather than the model object itself::
from django.db import models
class Car(models.Model): class Car(models.Model):
manufacturer = models.ForeignKey('Manufacturer') manufacturer = models.ForeignKey('Manufacturer')
# ... # ...
class Manufacturer(models.Model): class Manufacturer(models.Model):
# ... # ...
pass
To refer to models defined in another application, you can explicitly specify To refer to models defined in another application, you can explicitly specify
a model with the full application label. For example, if the ``Manufacturer`` a model with the full application label. For example, if the ``Manufacturer``
@ -1132,6 +1137,9 @@ The possible values for :attr:`~ForeignKey.on_delete` are found in
necessary to avoid executing queries at the time your models.py is necessary to avoid executing queries at the time your models.py is
imported:: imported::
from django.db import models
from django.contrib.auth.models import User
def get_sentinel_user(): def get_sentinel_user():
return User.objects.get_or_create(username='deleted')[0] return User.objects.get_or_create(username='deleted')[0]
@ -1204,6 +1212,8 @@ that control how the relationship functions.
Only used in the definition of ManyToManyFields on self. Consider the Only used in the definition of ManyToManyFields on self. Consider the
following model:: following model::
from django.db import models
class Person(models.Model): class Person(models.Model):
friends = models.ManyToManyField("self") friends = models.ManyToManyField("self")

View File

@ -34,6 +34,8 @@ that, you need to :meth:`~Model.save()`.
1. Add a classmethod on the model class:: 1. Add a classmethod on the model class::
from django.db import models
class Book(models.Model): class Book(models.Model):
title = models.CharField(max_length=100) title = models.CharField(max_length=100)
@ -105,6 +107,7 @@ individually.
You'll need to call ``full_clean`` manually when you want to run one-step model You'll need to call ``full_clean`` manually when you want to run one-step model
validation for your own manually created models. For example:: validation for your own manually created models. For example::
from django.core.exceptions import ValidationError
try: try:
article.full_clean() article.full_clean()
except ValidationError as e: except ValidationError as e:
@ -132,6 +135,7 @@ automatically provide a value for a field, or to do validation that requires
access to more than a single field:: access to more than a single field::
def clean(self): def clean(self):
import datetime
from django.core.exceptions import ValidationError from django.core.exceptions import ValidationError
# Don't allow draft entries to have a pub_date. # Don't allow draft entries to have a pub_date.
if self.status == 'draft' and self.pub_date is not None: if self.status == 'draft' and self.pub_date is not None:
@ -434,6 +438,8 @@ representation of the model from the ``__unicode__()`` method.
For example:: For example::
from django.db import models
class Person(models.Model): class Person(models.Model):
first_name = models.CharField(max_length=50) first_name = models.CharField(max_length=50)
last_name = models.CharField(max_length=50) last_name = models.CharField(max_length=50)
@ -460,6 +466,9 @@ Thus, you should return a nice, human-readable string for the object's
The previous :meth:`~Model.__unicode__()` example could be similarly written The previous :meth:`~Model.__unicode__()` example could be similarly written
using ``__str__()`` like this:: using ``__str__()`` like this::
from django.db import models
from django.utils.encoding import force_bytes
class Person(models.Model): class Person(models.Model):
first_name = models.CharField(max_length=50) first_name = models.CharField(max_length=50)
last_name = models.CharField(max_length=50) last_name = models.CharField(max_length=50)
@ -490,6 +499,7 @@ function is usually the best approach.)
For example:: For example::
def get_absolute_url(self): def get_absolute_url(self):
from django.core.urlresolvers import reverse
return reverse('people.views.details', args=[str(self.id)]) return reverse('people.views.details', args=[str(self.id)])
One place Django uses ``get_absolute_url()`` is in the admin app. If an object One place Django uses ``get_absolute_url()`` is in the admin app. If an object

View File

@ -145,6 +145,12 @@ Django quotes column and table names behind the scenes.
and a question has more than one answer, and the order of answers matters, you'd and a question has more than one answer, and the order of answers matters, you'd
do this:: do this::
from django.db import models
class Question(models.Model):
text = models.TextField()
# ...
class Answer(models.Model): class Answer(models.Model):
question = models.ForeignKey(Question) question = models.ForeignKey(Question)
# ... # ...

View File

@ -232,6 +232,7 @@ the model field that is being aggregated.
For example, if you were manipulating a list of blogs, you may want For example, if you were manipulating a list of blogs, you may want
to determine how many entries have been made in each blog:: to determine how many entries have been made in each blog::
>>> from django.db.models import Count
>>> q = Blog.objects.annotate(Count('entry')) >>> q = Blog.objects.annotate(Count('entry'))
# The name of the first blog # The name of the first blog
>>> q[0].name >>> q[0].name
@ -699,6 +700,8 @@ And here's ``select_related`` lookup::
``select_related()`` follows foreign keys as far as possible. If you have the ``select_related()`` follows foreign keys as far as possible. If you have the
following models:: following models::
from django.db import models
class City(models.Model): class City(models.Model):
# ... # ...
pass pass
@ -814,6 +817,8 @@ that are supported by ``select_related``. It also supports prefetching of
For example, suppose you have these models:: For example, suppose you have these models::
from django.db import models
class Topping(models.Model): class Topping(models.Model):
name = models.CharField(max_length=30) name = models.CharField(max_length=30)
@ -1565,6 +1570,7 @@ aggregated.
For example, when you are working with blog entries, you may want to know the For example, when you are working with blog entries, you may want to know the
number of authors that have contributed blog entries:: number of authors that have contributed blog entries::
>>> from django.db.models import Count
>>> q = Blog.objects.aggregate(Count('entry')) >>> q = Blog.objects.aggregate(Count('entry'))
{'entry__count': 16} {'entry__count': 16}
@ -2042,6 +2048,7 @@ Range test (inclusive).
Example:: Example::
import datetime
start_date = datetime.date(2005, 1, 1) start_date = datetime.date(2005, 1, 1)
end_date = datetime.date(2005, 3, 31) end_date = datetime.date(2005, 3, 31)
Entry.objects.filter(pub_date__range=(start_date, end_date)) Entry.objects.filter(pub_date__range=(start_date, end_date))

View File

@ -12,8 +12,11 @@ Related objects reference
* The "other side" of a :class:`~django.db.models.ForeignKey` relation. * The "other side" of a :class:`~django.db.models.ForeignKey` relation.
That is:: That is::
from django.db import models
class Reporter(models.Model): class Reporter(models.Model):
... # ...
pass
class Article(models.Model): class Article(models.Model):
reporter = models.ForeignKey(Reporter) reporter = models.ForeignKey(Reporter)
@ -24,7 +27,8 @@ Related objects reference
* Both sides of a :class:`~django.db.models.ManyToManyField` relation:: * Both sides of a :class:`~django.db.models.ManyToManyField` relation::
class Topping(models.Model): class Topping(models.Model):
... # ...
pass
class Pizza(models.Model): class Pizza(models.Model):
toppings = models.ManyToManyField(Topping) toppings = models.ManyToManyField(Topping)

View File

@ -18,27 +18,29 @@ used to track the inventory for a series of online bookstores:
.. code-block:: python .. code-block:: python
from django.db import models
class Author(models.Model): class Author(models.Model):
name = models.CharField(max_length=100) name = models.CharField(max_length=100)
age = models.IntegerField() age = models.IntegerField()
class Publisher(models.Model): class Publisher(models.Model):
name = models.CharField(max_length=300) name = models.CharField(max_length=300)
num_awards = models.IntegerField() num_awards = models.IntegerField()
class Book(models.Model): class Book(models.Model):
name = models.CharField(max_length=300) name = models.CharField(max_length=300)
pages = models.IntegerField() pages = models.IntegerField()
price = models.DecimalField(max_digits=10, decimal_places=2) price = models.DecimalField(max_digits=10, decimal_places=2)
rating = models.FloatField() rating = models.FloatField()
authors = models.ManyToManyField(Author) authors = models.ManyToManyField(Author)
publisher = models.ForeignKey(Publisher) publisher = models.ForeignKey(Publisher)
pubdate = models.DateField() pubdate = models.DateField()
class Store(models.Model): class Store(models.Model):
name = models.CharField(max_length=300) name = models.CharField(max_length=300)
books = models.ManyToManyField(Book) books = models.ManyToManyField(Book)
registered_users = models.PositiveIntegerField() registered_users = models.PositiveIntegerField()
Cheat sheet Cheat sheet
=========== ===========
@ -123,7 +125,7 @@ If you want to generate more than one aggregate, you just add another
argument to the ``aggregate()`` clause. So, if we also wanted to know argument to the ``aggregate()`` clause. So, if we also wanted to know
the maximum and minimum price of all books, we would issue the query:: the maximum and minimum price of all books, we would issue the query::
>>> from django.db.models import Avg, Max, Min, Count >>> from django.db.models import Avg, Max, Min
>>> Book.objects.aggregate(Avg('price'), Max('price'), Min('price')) >>> Book.objects.aggregate(Avg('price'), Max('price'), Min('price'))
{'price__avg': 34.35, 'price__max': Decimal('81.20'), 'price__min': Decimal('12.99')} {'price__avg': 34.35, 'price__max': Decimal('81.20'), 'price__min': Decimal('12.99')}
@ -148,6 +150,7 @@ the number of authors:
.. code-block:: python .. code-block:: python
# Build an annotated queryset # Build an annotated queryset
>>> from django.db.models import Count
>>> q = Book.objects.annotate(Count('authors')) >>> q = Book.objects.annotate(Count('authors'))
# Interrogate the first object in the queryset # Interrogate the first object in the queryset
>>> q[0] >>> q[0]
@ -192,6 +195,7 @@ and aggregate the related value.
For example, to find the price range of books offered in each store, For example, to find the price range of books offered in each store,
you could use the annotation:: you could use the annotation::
>>> from django.db.models import Max, Min
>>> Store.objects.annotate(min_price=Min('books__price'), max_price=Max('books__price')) >>> Store.objects.annotate(min_price=Min('books__price'), max_price=Max('books__price'))
This tells Django to retrieve the ``Store`` model, join (through the This tells Django to retrieve the ``Store`` model, join (through the
@ -222,7 +226,7 @@ For example, we can ask for all publishers, annotated with their respective
total book stock counters (note how we use ``'book'`` to specify the total book stock counters (note how we use ``'book'`` to specify the
``Publisher`` -> ``Book`` reverse foreign key hop):: ``Publisher`` -> ``Book`` reverse foreign key hop)::
>>> from django.db.models import Count, Min, Sum, Max, Avg >>> from django.db.models import Count, Min, Sum, Avg
>>> Publisher.objects.annotate(Count('book')) >>> Publisher.objects.annotate(Count('book'))
(Every ``Publisher`` in the resulting ``QuerySet`` will have an extra attribute (Every ``Publisher`` in the resulting ``QuerySet`` will have an extra attribute
@ -269,6 +273,7 @@ constraining the objects for which an annotation is calculated. For example,
you can generate an annotated list of all books that have a title starting you can generate an annotated list of all books that have a title starting
with "Django" using the query:: with "Django" using the query::
>>> from django.db.models import Count, Avg
>>> Book.objects.filter(name__startswith="Django").annotate(num_authors=Count('authors')) >>> Book.objects.filter(name__startswith="Django").annotate(num_authors=Count('authors'))
When used with an ``aggregate()`` clause, a filter has the effect of When used with an ``aggregate()`` clause, a filter has the effect of
@ -407,6 +412,8 @@ particularly, when counting things.
By way of example, suppose you have a model like this:: By way of example, suppose you have a model like this::
from django.db import models
class Item(models.Model): class Item(models.Model):
name = models.CharField(max_length=10) name = models.CharField(max_length=10)
data = models.IntegerField() data = models.IntegerField()
@ -457,5 +464,6 @@ For example, if you wanted to calculate the average number of authors per
book you first annotate the set of books with the author count, then book you first annotate the set of books with the author count, then
aggregate that author count, referencing the annotation field:: aggregate that author count, referencing the annotation field::
>>> from django.db.models import Count, Avg
>>> Book.objects.annotate(num_authors=Count('authors')).aggregate(Avg('num_authors')) >>> Book.objects.annotate(num_authors=Count('authors')).aggregate(Avg('num_authors'))
{'num_authors__avg': 1.66} {'num_authors__avg': 1.66}

View File

@ -62,6 +62,8 @@ For example, this custom ``Manager`` offers a method ``with_counts()``, which
returns a list of all ``OpinionPoll`` objects, each with an extra returns a list of all ``OpinionPoll`` objects, each with an extra
``num_responses`` attribute that is the result of an aggregate query:: ``num_responses`` attribute that is the result of an aggregate query::
from django.db import models
class PollManager(models.Manager): class PollManager(models.Manager):
def with_counts(self): def with_counts(self):
from django.db import connection from django.db import connection
@ -101,6 +103,8 @@ Modifying initial Manager QuerySets
A ``Manager``'s base ``QuerySet`` returns all objects in the system. For A ``Manager``'s base ``QuerySet`` returns all objects in the system. For
example, using this model:: example, using this model::
from django.db import models
class Book(models.Model): class Book(models.Model):
title = models.CharField(max_length=100) title = models.CharField(max_length=100)
author = models.CharField(max_length=50) author = models.CharField(max_length=50)
@ -236,7 +240,7 @@ class, but still customize the default manager. For example, suppose you have
this base class:: this base class::
class AbstractBase(models.Model): class AbstractBase(models.Model):
... # ...
objects = CustomManager() objects = CustomManager()
class Meta: class Meta:
@ -246,14 +250,15 @@ If you use this directly in a subclass, ``objects`` will be the default
manager if you declare no managers in the base class:: manager if you declare no managers in the base class::
class ChildA(AbstractBase): class ChildA(AbstractBase):
... # ...
# This class has CustomManager as the default manager. # This class has CustomManager as the default manager.
pass
If you want to inherit from ``AbstractBase``, but provide a different default If you want to inherit from ``AbstractBase``, but provide a different default
manager, you can provide the default manager on the child class:: manager, you can provide the default manager on the child class::
class ChildB(AbstractBase): class ChildB(AbstractBase):
... # ...
# An explicit default manager. # An explicit default manager.
default_manager = OtherManager() default_manager = OtherManager()
@ -274,9 +279,10 @@ it into the inheritance hierarchy *after* the defaults::
abstract = True abstract = True
class ChildC(AbstractBase, ExtraManager): class ChildC(AbstractBase, ExtraManager):
... # ...
# Default manager is CustomManager, but OtherManager is # Default manager is CustomManager, but OtherManager is
# also available via the "extra_manager" attribute. # also available via the "extra_manager" attribute.
pass
Note that while you can *define* a custom manager on the abstract model, you Note that while you can *define* a custom manager on the abstract model, you
can't *invoke* any methods using the abstract model. That is:: can't *invoke* any methods using the abstract model. That is::
@ -349,8 +355,7 @@ the manager class::
class MyManager(models.Manager): class MyManager(models.Manager):
use_for_related_fields = True use_for_related_fields = True
# ...
...
If this attribute is set on the *default* manager for a model (only the If this attribute is set on the *default* manager for a model (only the
default manager is considered in these situations), Django will use that class default manager is considered in these situations), Django will use that class
@ -396,7 +401,8 @@ it, whereas the following will not work::
# BAD: Incorrect code # BAD: Incorrect code
class MyManager(models.Manager): class MyManager(models.Manager):
... # ...
pass
# Sets the attribute on an instance of MyManager. Django will # Sets the attribute on an instance of MyManager. Django will
# ignore this setting. # ignore this setting.
@ -404,7 +410,7 @@ it, whereas the following will not work::
mgr.use_for_related_fields = True mgr.use_for_related_fields = True
class MyModel(models.Model): class MyModel(models.Model):
... # ...
objects = mgr objects = mgr
# End of incorrect code. # End of incorrect code.

View File

@ -90,6 +90,8 @@ attributes. Be careful not to choose field names that conflict with the
Example:: Example::
from django.db import models
class Musician(models.Model): class Musician(models.Model):
first_name = models.CharField(max_length=50) first_name = models.CharField(max_length=50)
last_name = models.CharField(max_length=50) last_name = models.CharField(max_length=50)
@ -290,8 +292,11 @@ For example, if a ``Car`` model has a ``Manufacturer`` -- that is, a
``Manufacturer`` makes multiple cars but each ``Car`` only has one ``Manufacturer`` makes multiple cars but each ``Car`` only has one
``Manufacturer`` -- use the following definitions:: ``Manufacturer`` -- use the following definitions::
from django.db import models
class Manufacturer(models.Model): class Manufacturer(models.Model):
# ... # ...
pass
class Car(models.Model): class Car(models.Model):
manufacturer = models.ForeignKey(Manufacturer) manufacturer = models.ForeignKey(Manufacturer)
@ -340,8 +345,11 @@ For example, if a ``Pizza`` has multiple ``Topping`` objects -- that is, a
``Topping`` can be on multiple pizzas and each ``Pizza`` has multiple toppings ``Topping`` can be on multiple pizzas and each ``Pizza`` has multiple toppings
-- here's how you'd represent that:: -- here's how you'd represent that::
from django.db import models
class Topping(models.Model): class Topping(models.Model):
# ... # ...
pass
class Pizza(models.Model): class Pizza(models.Model):
# ... # ...
@ -403,6 +411,8 @@ intermediate model. The intermediate model is associated with the
that will act as an intermediary. For our musician example, the code would look that will act as an intermediary. For our musician example, the code would look
something like this:: something like this::
from django.db import models
class Person(models.Model): class Person(models.Model):
name = models.CharField(max_length=128) name = models.CharField(max_length=128)
@ -583,6 +593,7 @@ 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, the related model at the top of the file where your model is defined. Then,
just refer to the other model class wherever needed. For example:: just refer to the other model class wherever needed. For example::
from django.db import models
from geography.models import ZipCode from geography.models import ZipCode
class Restaurant(models.Model): class Restaurant(models.Model):
@ -630,6 +641,8 @@ Meta options
Give your model metadata by using an inner ``class Meta``, like so:: Give your model metadata by using an inner ``class Meta``, like so::
from django.db import models
class Ox(models.Model): class Ox(models.Model):
horn_length = models.IntegerField() horn_length = models.IntegerField()
@ -660,6 +673,8 @@ model.
For example, this model has a few custom methods:: For example, this model has a few custom methods::
from django.db import models
class Person(models.Model): class Person(models.Model):
first_name = models.CharField(max_length=50) first_name = models.CharField(max_length=50)
last_name = models.CharField(max_length=50) last_name = models.CharField(max_length=50)
@ -729,6 +744,8 @@ 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 to happen whenever you save an object. For example (see
:meth:`~Model.save` for documentation of the parameters it accepts):: :meth:`~Model.save` for documentation of the parameters it accepts)::
from django.db import models
class Blog(models.Model): class Blog(models.Model):
name = models.CharField(max_length=100) name = models.CharField(max_length=100)
tagline = models.TextField() tagline = models.TextField()
@ -740,6 +757,8 @@ to happen whenever you save an object. For example (see
You can also prevent saving:: You can also prevent saving::
from django.db import models
class Blog(models.Model): class Blog(models.Model):
name = models.CharField(max_length=100) name = models.CharField(max_length=100)
tagline = models.TextField() tagline = models.TextField()
@ -826,6 +845,8 @@ the child (and Django will raise an exception).
An example:: An example::
from django.db import models
class CommonInfo(models.Model): class CommonInfo(models.Model):
name = models.CharField(max_length=100) name = models.CharField(max_length=100)
age = models.PositiveIntegerField() age = models.PositiveIntegerField()
@ -854,14 +875,16 @@ 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 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:: 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 CommonInfo(models.Model):
... # ...
class Meta: class Meta:
abstract = True abstract = True
ordering = ['name'] ordering = ['name']
class Student(CommonInfo): class Student(CommonInfo):
... # ...
class Meta(CommonInfo.Meta): class Meta(CommonInfo.Meta):
db_table = 'student_info' db_table = 'student_info'
@ -901,6 +924,8 @@ abstract base class (only), part of the name should contain
For example, given an app ``common/models.py``:: For example, given an app ``common/models.py``::
from django.db import models
class Base(models.Model): class Base(models.Model):
m2m = models.ManyToManyField(OtherModel, related_name="%(app_label)s_%(class)s_related") m2m = models.ManyToManyField(OtherModel, related_name="%(app_label)s_%(class)s_related")
@ -949,6 +974,8 @@ relationship introduces links between the child model and each of its parents
(via an automatically-created :class:`~django.db.models.OneToOneField`). (via an automatically-created :class:`~django.db.models.OneToOneField`).
For example:: For example::
from django.db import models
class Place(models.Model): class Place(models.Model):
name = models.CharField(max_length=50) name = models.CharField(max_length=50)
address = models.CharField(max_length=80) address = models.CharField(max_length=80)
@ -998,7 +1025,7 @@ If the parent has an ordering and you don't want the child to have any natural
ordering, you can explicitly disable it:: ordering, you can explicitly disable it::
class ChildModel(ParentModel): class ChildModel(ParentModel):
... # ...
class Meta: class Meta:
# Remove parent's ordering effect # Remove parent's ordering effect
ordering = [] ordering = []
@ -1061,15 +1088,21 @@ 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 proxy model by setting the :attr:`~django.db.models.Options.proxy` attribute of
the ``Meta`` class to ``True``. the ``Meta`` class to ``True``.
For example, suppose you want to add a method to the ``Person`` model described For example, suppose you want to add a method to the ``Person`` model. You can do it like this::
above. 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 MyPerson(Person):
class Meta: class Meta:
proxy = True proxy = True
def do_something(self): def do_something(self):
... # ...
pass
The ``MyPerson`` class operates on the same database table as its parent The ``MyPerson`` class operates on the same database table as its parent
``Person`` class. In particular, any new instances of ``Person`` will also be ``Person`` class. In particular, any new instances of ``Person`` will also be
@ -1125,8 +1158,11 @@ classes will still be available.
Continuing our example from above, you could change the default manager used Continuing our example from above, you could change the default manager used
when you query the ``Person`` model like this:: when you query the ``Person`` model like this::
from django.db import models
class NewManager(models.Manager): class NewManager(models.Manager):
... # ...
pass
class MyPerson(Person): class MyPerson(Person):
objects = NewManager() objects = NewManager()

View File

@ -17,6 +17,8 @@ models, which comprise a Weblog application:
.. code-block:: python .. code-block:: python
from django.db import models
class Blog(models.Model): class Blog(models.Model):
name = models.CharField(max_length=100) name = models.CharField(max_length=100)
tagline = models.TextField() tagline = models.TextField()