mirror of
https://github.com/django/django.git
synced 2025-08-04 19:08:28 +00:00
Fixed #122 -- BIG, BACKWARDS-INCOMPATIBLE CHANGE. Changed model syntax to use fieldname=FieldClass() syntax. See ModelSyntaxChangeInstructions for important information on how to change your models
git-svn-id: http://code.djangoproject.com/svn/django/trunk@549 bcc190cf-cafb-0310-a4f2-bffc1f526a37
This commit is contained in:
parent
aec0a73d73
commit
25264c8604
36 changed files with 956 additions and 720 deletions
|
@ -1,3 +1,4 @@
|
|||
__all__ = ['basic', 'repr', 'custom_methods', 'many_to_one', 'many_to_many',
|
||||
'ordering', 'lookup', 'get_latest', 'm2m_intermediary', 'one_to_one',
|
||||
'm2o_recursive', 'm2o_recursive2', 'save_delete_hooks', 'custom_pk']
|
||||
'm2o_recursive', 'm2o_recursive2', 'save_delete_hooks', 'custom_pk',
|
||||
'subclassing', 'many_to_one_null']
|
||||
|
|
|
@ -7,10 +7,8 @@ This is a basic model with only two non-primary-key fields.
|
|||
from django.core import meta
|
||||
|
||||
class Article(meta.Model):
|
||||
fields = (
|
||||
meta.CharField('headline', maxlength=100, default='Default headline'),
|
||||
meta.DateTimeField('pub_date'),
|
||||
)
|
||||
headline = meta.CharField(maxlength=100, default='Default headline')
|
||||
pub_date = meta.DateTimeField()
|
||||
|
||||
API_TESTS = """
|
||||
# No articles are in the system yet.
|
||||
|
|
|
@ -23,10 +23,8 @@ namespace as custom methods.
|
|||
from django.core import meta
|
||||
|
||||
class Article(meta.Model):
|
||||
fields = (
|
||||
meta.CharField('headline', maxlength=100),
|
||||
meta.DateField('pub_date'),
|
||||
)
|
||||
headline = meta.CharField(maxlength=100)
|
||||
pub_date = meta.DateField()
|
||||
|
||||
def __repr__(self):
|
||||
return self.headline
|
||||
|
|
|
@ -11,12 +11,11 @@ fails.
|
|||
from django.core import meta
|
||||
|
||||
class Employee(meta.Model):
|
||||
fields = (
|
||||
meta.CharField('employee_code', maxlength=10, primary_key=True),
|
||||
meta.CharField('first_name', maxlength=20),
|
||||
meta.CharField('last_name', maxlength=20),
|
||||
)
|
||||
ordering = ('last_name', 'first_name')
|
||||
employee_code = meta.CharField(maxlength=10, primary_key=True)
|
||||
first_name = meta.CharField(maxlength=20)
|
||||
last_name = meta.CharField(maxlength=20)
|
||||
class META:
|
||||
ordering = ('last_name', 'first_name')
|
||||
|
||||
def __repr__(self):
|
||||
return "%s %s" % (self.first_name, self.last_name)
|
||||
|
|
|
@ -11,11 +11,10 @@ date farthest into the future."
|
|||
from django.core import meta
|
||||
|
||||
class Article(meta.Model):
|
||||
fields = (
|
||||
meta.CharField('headline', maxlength=100),
|
||||
meta.DateTimeField('pub_date'),
|
||||
)
|
||||
get_latest_by = 'pub_date'
|
||||
headline = meta.CharField(maxlength=100)
|
||||
pub_date = meta.DateTimeField()
|
||||
class META:
|
||||
get_latest_by = 'pub_date'
|
||||
|
||||
def __repr__(self):
|
||||
return self.headline
|
||||
|
|
|
@ -7,11 +7,10 @@ This demonstrates features of the database API.
|
|||
from django.core import meta
|
||||
|
||||
class Article(meta.Model):
|
||||
fields = (
|
||||
meta.CharField('headline', maxlength=100),
|
||||
meta.DateTimeField('pub_date'),
|
||||
)
|
||||
ordering = ('-pub_date', 'headline')
|
||||
headline = meta.CharField(maxlength=100)
|
||||
pub_date = meta.DateTimeField()
|
||||
class META:
|
||||
ordering = ('-pub_date', 'headline')
|
||||
|
||||
def __repr__(self):
|
||||
return self.headline
|
||||
|
|
|
@ -13,49 +13,43 @@ writer").
|
|||
from django.core import meta
|
||||
|
||||
class Reporter(meta.Model):
|
||||
fields = (
|
||||
meta.CharField('first_name', maxlength=30),
|
||||
meta.CharField('last_name', maxlength=30),
|
||||
)
|
||||
first_name = meta.CharField(maxlength=30)
|
||||
last_name = meta.CharField(maxlength=30)
|
||||
|
||||
def __repr__(self):
|
||||
return "%s %s" % (self.first_name, self.last_name)
|
||||
|
||||
class Article(meta.Model):
|
||||
fields = (
|
||||
meta.CharField('headline', maxlength=100),
|
||||
meta.DateField('pub_date'),
|
||||
)
|
||||
headline = meta.CharField(maxlength=100)
|
||||
pub_date = meta.DateField()
|
||||
|
||||
def __repr__(self):
|
||||
return self.headline
|
||||
|
||||
class Writer(meta.Model):
|
||||
fields = (
|
||||
meta.ForeignKey(Reporter),
|
||||
meta.ForeignKey(Article),
|
||||
meta.CharField('position', maxlength=100),
|
||||
)
|
||||
reporter = meta.ForeignKey(Reporter)
|
||||
article = meta.ForeignKey(Article)
|
||||
position = meta.CharField(maxlength=100)
|
||||
|
||||
def __repr__(self):
|
||||
return '%r (%s)' % (self.get_reporter(), self.position)
|
||||
|
||||
API_TESTS = """
|
||||
# Create a few Reporters.
|
||||
>>> r1 = reporters.Reporter(id=None, first_name='John', last_name='Smith')
|
||||
>>> r1 = reporters.Reporter(first_name='John', last_name='Smith')
|
||||
>>> r1.save()
|
||||
>>> r2 = reporters.Reporter(id=None, first_name='Jane', last_name='Doe')
|
||||
>>> r2 = reporters.Reporter(first_name='Jane', last_name='Doe')
|
||||
>>> r2.save()
|
||||
|
||||
# Create an Article.
|
||||
>>> from datetime import datetime
|
||||
>>> a = articles.Article(id=None, headline='This is a test', pub_date=datetime(2005, 7, 27))
|
||||
>>> a = articles.Article(headline='This is a test', pub_date=datetime(2005, 7, 27))
|
||||
>>> a.save()
|
||||
|
||||
# Create a few Writers.
|
||||
>>> w1 = writers.Writer(id=None, reporter_id=r1.id, article_id=a.id, position='Main writer')
|
||||
>>> w1 = writers.Writer(reporter=r1, article=a, position='Main writer')
|
||||
>>> w1.save()
|
||||
>>> w2 = writers.Writer(id=None, reporter_id=r2.id, article_id=a.id, position='Contributor')
|
||||
>>> w2 = writers.Writer(reporter=r2, article=a, position='Contributor')
|
||||
>>> w2.save()
|
||||
|
||||
# Play around with the API.
|
||||
|
|
|
@ -7,29 +7,25 @@ To define a many-to-one relationship between a model and itself, use
|
|||
In this example, a ``Category`` is related to itself. That is, each
|
||||
``Category`` has a parent ``Category``.
|
||||
|
||||
Because of this recursive relationship, we need to tell Django what the
|
||||
relationships should be called. Set ``rel_name`` for this, and set
|
||||
``related_name`` to designate what the reverse relationship is called.
|
||||
Set ``related_name`` to designate what the reverse relationship is called.
|
||||
"""
|
||||
|
||||
from django.core import meta
|
||||
|
||||
class Category(meta.Model):
|
||||
module_name = 'categories'
|
||||
fields = (
|
||||
meta.CharField('name', maxlength=20),
|
||||
meta.ForeignKey('self', null=True,
|
||||
rel_name='parent', related_name='child'),
|
||||
)
|
||||
name = meta.CharField(maxlength=20)
|
||||
parent = meta.ForeignKey('self', null=True, related_name='child')
|
||||
class META:
|
||||
module_name = 'categories'
|
||||
|
||||
def __repr__(self):
|
||||
return self.name
|
||||
|
||||
API_TESTS = """
|
||||
# Create a few Category objects.
|
||||
>>> r = categories.Category(id=None, name='Root category', parent_id=None)
|
||||
>>> r = categories.Category(id=None, name='Root category', parent=None)
|
||||
>>> r.save()
|
||||
>>> c = categories.Category(id=None, name='Child category', parent_id=r.id)
|
||||
>>> c = categories.Category(id=None, name='Child category', parent=r)
|
||||
>>> c.save()
|
||||
|
||||
>>> r.get_child_list()
|
||||
|
|
|
@ -4,36 +4,28 @@
|
|||
In this example, a ``Person`` can have a ``mother`` and ``father`` -- both of
|
||||
which are other ``Person`` objects.
|
||||
|
||||
Because a ``Person`` has multiple relationships to ``Person``, we need to
|
||||
distinguish the relationships. Set ``rel_name`` to tell Django what the
|
||||
relationship should be called, because ``Person`` has two relationships to the
|
||||
same model. Also, set ``related_name`` to designate what the reverse
|
||||
relationship is called.
|
||||
Set ``related_name`` to designate what the reverse relationship is called.
|
||||
"""
|
||||
|
||||
from django.core import meta
|
||||
|
||||
class Person(meta.Model):
|
||||
fields = (
|
||||
meta.CharField('full_name', maxlength=20),
|
||||
meta.ForeignKey('self', null=True, rel_name='mother',
|
||||
related_name='mothers_child'),
|
||||
meta.ForeignKey('self', null=True, rel_name='father',
|
||||
related_name='fathers_child'),
|
||||
)
|
||||
full_name = meta.CharField(maxlength=20)
|
||||
mother = meta.ForeignKey('self', null=True, related_name='mothers_child')
|
||||
father = meta.ForeignKey('self', null=True, related_name='fathers_child')
|
||||
|
||||
def __repr__(self):
|
||||
return self.full_name
|
||||
|
||||
API_TESTS = """
|
||||
# Create two Person objects -- the mom and dad in our family.
|
||||
>>> dad = persons.Person(id=None, full_name='John Smith Senior', mother_id=None, father_id=None)
|
||||
>>> dad = persons.Person(full_name='John Smith Senior', mother=None, father=None)
|
||||
>>> dad.save()
|
||||
>>> mom = persons.Person(id=None, full_name='Jane Smith', mother_id=None, father_id=None)
|
||||
>>> mom = persons.Person(full_name='Jane Smith', mother=None, father=None)
|
||||
>>> mom.save()
|
||||
|
||||
# Give mom and dad a kid.
|
||||
>>> kid = persons.Person(id=None, full_name='John Smith Junior', mother_id=mom.id, father_id=dad.id)
|
||||
>>> kid = persons.Person(full_name='John Smith Junior', mother=mom, father=dad)
|
||||
>>> kid.save()
|
||||
|
||||
>>> kid.get_mother()
|
||||
|
|
|
@ -10,18 +10,14 @@ and a publication has multiple articles.
|
|||
from django.core import meta
|
||||
|
||||
class Publication(meta.Model):
|
||||
fields = (
|
||||
meta.CharField('title', maxlength=30),
|
||||
)
|
||||
title = meta.CharField(maxlength=30)
|
||||
|
||||
def __repr__(self):
|
||||
return self.title
|
||||
|
||||
class Article(meta.Model):
|
||||
fields = (
|
||||
meta.CharField('headline', maxlength=100),
|
||||
meta.ManyToManyField(Publication),
|
||||
)
|
||||
headline = meta.CharField(maxlength=100)
|
||||
publications = meta.ManyToManyField(Publication)
|
||||
|
||||
def __repr__(self):
|
||||
return self.headline
|
||||
|
|
|
@ -1,42 +1,38 @@
|
|||
"""
|
||||
4. Many-to-one relationships
|
||||
|
||||
To define a many-to-one relationship, use ForeignKey().
|
||||
To define a many-to-one relationship, use ``ForeignKey()`` .
|
||||
"""
|
||||
|
||||
from django.core import meta
|
||||
|
||||
class Reporter(meta.Model):
|
||||
fields = (
|
||||
meta.CharField('first_name', maxlength=30),
|
||||
meta.CharField('last_name', maxlength=30),
|
||||
)
|
||||
first_name = meta.CharField(maxlength=30)
|
||||
last_name = meta.CharField(maxlength=30)
|
||||
|
||||
def __repr__(self):
|
||||
return "%s %s" % (self.first_name, self.last_name)
|
||||
|
||||
class Article(meta.Model):
|
||||
fields = (
|
||||
meta.CharField('headline', maxlength=100),
|
||||
meta.DateField('pub_date'),
|
||||
meta.ForeignKey(Reporter),
|
||||
)
|
||||
headline = meta.CharField(maxlength=100)
|
||||
pub_date = meta.DateField()
|
||||
reporter = meta.ForeignKey(Reporter)
|
||||
|
||||
def __repr__(self):
|
||||
return self.headline
|
||||
|
||||
API_TESTS = """
|
||||
# Create a Reporter.
|
||||
>>> r = reporters.Reporter(id=None, first_name='John', last_name='Smith')
|
||||
>>> r = reporters.Reporter(first_name='John', last_name='Smith')
|
||||
>>> r.save()
|
||||
|
||||
# Create an Article.
|
||||
>>> from datetime import datetime
|
||||
>>> a = articles.Article(id=None, headline='This is a test', pub_date=datetime(2005, 7, 27), reporter_id=r.id)
|
||||
>>> a = articles.Article(id=None, headline="This is a test", pub_date=datetime(2005, 7, 27), reporter=r)
|
||||
>>> a.save()
|
||||
|
||||
>>> a.reporter_id
|
||||
1L
|
||||
1
|
||||
|
||||
>>> a.get_reporter()
|
||||
John Smith
|
||||
|
@ -47,7 +43,7 @@ John Smith
|
|||
('John', 'Smith')
|
||||
|
||||
# Create an Article via the Reporter object.
|
||||
>>> new_article = r.add_article(headline="John's second story", pub_date=datetime(2005, 7, 28))
|
||||
>>> new_article = r.add_article(headline="John's second story", pub_date=datetime(2005, 7, 29))
|
||||
>>> new_article
|
||||
John's second story
|
||||
>>> new_article.reporter_id
|
||||
|
@ -61,7 +57,7 @@ John's second story
|
|||
This is a test
|
||||
|
||||
>>> r.get_article_count()
|
||||
2L
|
||||
2
|
||||
|
||||
# The API automatically follows relationships as far as you need.
|
||||
# Use double underscores to separate relationships.
|
||||
|
@ -70,4 +66,32 @@ This is a test
|
|||
>>> articles.get_list(reporter__first_name__exact='John', order_by=['pub_date'])
|
||||
[This is a test, John's second story]
|
||||
|
||||
# Find all Articles for the Reporter whose ID is 1.
|
||||
>>> articles.get_list(reporter__id__exact=1, order_by=['pub_date'])
|
||||
[This is a test, John's second story]
|
||||
|
||||
# Note you need two underscores between "reporter" and "id" -- not one.
|
||||
>>> articles.get_list(reporter_id__exact=1)
|
||||
Traceback (most recent call last):
|
||||
...
|
||||
TypeError: got unexpected keyword argument 'reporter_id__exact'
|
||||
|
||||
# "pk" shortcut syntax works in a related context, too.
|
||||
>>> articles.get_list(reporter__pk=1, order_by=['pub_date'])
|
||||
[This is a test, John's second story]
|
||||
|
||||
# You can also instantiate an Article by passing
|
||||
# the Reporter's ID instead of a Reporter object.
|
||||
>>> a3 = articles.Article(id=None, headline="This is a test", pub_date=datetime(2005, 7, 27), reporter_id=r.id)
|
||||
>>> a3.save()
|
||||
>>> a3.reporter_id
|
||||
1
|
||||
>>> a3.get_reporter()
|
||||
John Smith
|
||||
|
||||
# Similarly, the reporter ID can be a string.
|
||||
>>> a4 = articles.Article(id=None, headline="This is a test", pub_date=datetime(2005, 7, 27), reporter_id="1")
|
||||
>>> a4.save()
|
||||
>>> a4.get_reporter()
|
||||
John Smith
|
||||
"""
|
||||
|
|
77
tests/testapp/models/many_to_one_null.py
Normal file
77
tests/testapp/models/many_to_one_null.py
Normal file
|
@ -0,0 +1,77 @@
|
|||
"""
|
||||
16. Many-to-one relationships that can be null
|
||||
|
||||
To define a many-to-one relationship, use ``ForeignKey()`` with ``null=True`` .
|
||||
"""
|
||||
|
||||
from django.core import meta
|
||||
|
||||
class Reporter(meta.Model):
|
||||
name = meta.CharField(maxlength=30)
|
||||
|
||||
def __repr__(self):
|
||||
return self.name
|
||||
|
||||
class Article(meta.Model):
|
||||
headline = meta.CharField(maxlength=100)
|
||||
reporter = meta.ForeignKey(Reporter, null=True)
|
||||
|
||||
def __repr__(self):
|
||||
return self.headline
|
||||
|
||||
API_TESTS = """
|
||||
# Create a Reporter.
|
||||
>>> r = reporters.Reporter(name='John Smith')
|
||||
>>> r.save()
|
||||
|
||||
# Create an Article.
|
||||
>>> a = articles.Article(headline="First", reporter=r)
|
||||
>>> a.save()
|
||||
|
||||
>>> a.reporter_id
|
||||
1
|
||||
|
||||
>>> a.get_reporter()
|
||||
John Smith
|
||||
|
||||
# Article objects have access to their related Reporter objects.
|
||||
>>> r = a.get_reporter()
|
||||
|
||||
# Create an Article via the Reporter object.
|
||||
>>> a2 = r.add_article(headline="Second")
|
||||
>>> a2
|
||||
Second
|
||||
>>> a2.reporter_id
|
||||
1
|
||||
|
||||
# Reporter objects have access to their related Article objects.
|
||||
>>> r.get_article_list(order_by=['headline'])
|
||||
[First, Second]
|
||||
>>> r.get_article(headline__startswith='Fir')
|
||||
First
|
||||
>>> r.get_article_count()
|
||||
2
|
||||
|
||||
# Create an Article with no Reporter by passing "reporter=None".
|
||||
>>> a3 = articles.Article(headline="Third", reporter=None)
|
||||
>>> a3.save()
|
||||
>>> a3.id
|
||||
3
|
||||
>>> a3.reporter_id
|
||||
>>> print a3.reporter_id
|
||||
None
|
||||
>>> a3 = articles.get_object(pk=3)
|
||||
>>> print a3.reporter_id
|
||||
None
|
||||
|
||||
# An article's get_reporter() method throws ReporterDoesNotExist
|
||||
# if the reporter is set to None.
|
||||
>>> a3.get_reporter()
|
||||
Traceback (most recent call last):
|
||||
...
|
||||
ReporterDoesNotExist
|
||||
|
||||
# To retrieve the articles with no reporters set, use "reporter__isnull=True".
|
||||
>>> articles.get_list(reporter__isnull=True)
|
||||
[Third]
|
||||
"""
|
|
@ -9,33 +9,29 @@ In this example, a ``Place`` optionally can be a ``Restaurant``.
|
|||
from django.core import meta
|
||||
|
||||
class Place(meta.Model):
|
||||
fields = (
|
||||
meta.CharField('name', maxlength=50),
|
||||
meta.CharField('address', maxlength=80),
|
||||
)
|
||||
name = meta.CharField(maxlength=50)
|
||||
address = meta.CharField(maxlength=80)
|
||||
|
||||
def __repr__(self):
|
||||
return "%s the place" % self.name
|
||||
|
||||
class Restaurant(meta.Model):
|
||||
fields = (
|
||||
meta.OneToOneField(Place),
|
||||
meta.BooleanField('serves_hot_dogs'),
|
||||
meta.BooleanField('serves_pizza'),
|
||||
)
|
||||
place = meta.OneToOneField(Place)
|
||||
serves_hot_dogs = meta.BooleanField()
|
||||
serves_pizza = meta.BooleanField()
|
||||
|
||||
def __repr__(self):
|
||||
return "%s the restaurant" % self.get_place().name
|
||||
|
||||
API_TESTS = """
|
||||
# Create a couple of Places.
|
||||
>>> p1 = places.Place(id=None, name='Demon Dogs', address='944 W. Fullerton')
|
||||
>>> p1 = places.Place(name='Demon Dogs', address='944 W. Fullerton')
|
||||
>>> p1.save()
|
||||
>>> p2 = places.Place(id=None, name='Ace Hardware', address='1013 N. Ashland')
|
||||
>>> p2 = places.Place(name='Ace Hardware', address='1013 N. Ashland')
|
||||
>>> p2.save()
|
||||
|
||||
# Create a Restaurant. Pass the ID of the "parent" object as this object's ID.
|
||||
>>> r = restaurants.Restaurant(id=p1.id, serves_hot_dogs=True, serves_pizza=False)
|
||||
>>> r = restaurants.Restaurant(place=p1, serves_hot_dogs=True, serves_pizza=False)
|
||||
>>> r.save()
|
||||
|
||||
# A Restaurant can access its place.
|
||||
|
@ -50,7 +46,7 @@ Demon Dogs the restaurant
|
|||
>>> p2.get_restaurant()
|
||||
Traceback (most recent call last):
|
||||
...
|
||||
RestaurantDoesNotExist: Restaurant does not exist for {'id__exact': ...}
|
||||
RestaurantDoesNotExist: Restaurant does not exist for {'place__id__exact': ...}
|
||||
|
||||
# restaurants.get_list() just returns the Restaurants, not the Places.
|
||||
>>> restaurants.get_list()
|
||||
|
@ -60,4 +56,9 @@ RestaurantDoesNotExist: Restaurant does not exist for {'id__exact': ...}
|
|||
# Restaurants.
|
||||
>>> places.get_list(order_by=['name'])
|
||||
[Ace Hardware the place, Demon Dogs the place]
|
||||
|
||||
>>> restaurants.get_object(place__id__exact=1)
|
||||
Demon Dogs the restaurant
|
||||
>>> restaurants.get_object(pk=1)
|
||||
Demon Dogs the restaurant
|
||||
"""
|
||||
|
|
|
@ -16,11 +16,10 @@ undefined -- not random, just undefined.
|
|||
from django.core import meta
|
||||
|
||||
class Article(meta.Model):
|
||||
fields = (
|
||||
meta.CharField('headline', maxlength=100),
|
||||
meta.DateTimeField('pub_date'),
|
||||
)
|
||||
ordering = ('-pub_date', 'headline')
|
||||
headline = meta.CharField(maxlength=100)
|
||||
pub_date = meta.DateTimeField()
|
||||
class META:
|
||||
ordering = ('-pub_date', 'headline')
|
||||
|
||||
def __repr__(self):
|
||||
return self.headline
|
||||
|
@ -28,13 +27,13 @@ class Article(meta.Model):
|
|||
API_TESTS = """
|
||||
# Create a couple of Articles.
|
||||
>>> from datetime import datetime
|
||||
>>> a1 = articles.Article(id=None, headline='Article 1', pub_date=datetime(2005, 7, 26))
|
||||
>>> a1 = articles.Article(headline='Article 1', pub_date=datetime(2005, 7, 26))
|
||||
>>> a1.save()
|
||||
>>> a2 = articles.Article(id=None, headline='Article 2', pub_date=datetime(2005, 7, 27))
|
||||
>>> a2 = articles.Article(headline='Article 2', pub_date=datetime(2005, 7, 27))
|
||||
>>> a2.save()
|
||||
>>> a3 = articles.Article(id=None, headline='Article 3', pub_date=datetime(2005, 7, 27))
|
||||
>>> a3 = articles.Article(headline='Article 3', pub_date=datetime(2005, 7, 27))
|
||||
>>> a3.save()
|
||||
>>> a4 = articles.Article(id=None, headline='Article 4', pub_date=datetime(2005, 7, 28))
|
||||
>>> a4 = articles.Article(headline='Article 4', pub_date=datetime(2005, 7, 28))
|
||||
>>> a4.save()
|
||||
|
||||
# By default, articles.get_list() orders by pub_date descending, then
|
||||
|
|
|
@ -11,10 +11,8 @@ automatically-generated admin.
|
|||
from django.core import meta
|
||||
|
||||
class Article(meta.Model):
|
||||
fields = (
|
||||
meta.CharField('headline', maxlength=100),
|
||||
meta.DateTimeField('pub_date'),
|
||||
)
|
||||
headline = meta.CharField(maxlength=100)
|
||||
pub_date = meta.DateTimeField()
|
||||
|
||||
def __repr__(self):
|
||||
return self.headline
|
||||
|
@ -22,7 +20,7 @@ class Article(meta.Model):
|
|||
API_TESTS = """
|
||||
# Create an Article.
|
||||
>>> from datetime import datetime
|
||||
>>> a = articles.Article(id=None, headline='Area man programs in Python', pub_date=datetime(2005, 7, 28))
|
||||
>>> a = articles.Article(headline='Area man programs in Python', pub_date=datetime(2005, 7, 28))
|
||||
>>> a.save()
|
||||
|
||||
>>> repr(a)
|
||||
|
|
|
@ -13,10 +13,8 @@ Django provides hooks for executing arbitrary code around ``save()`` and
|
|||
from django.core import meta
|
||||
|
||||
class Person(meta.Model):
|
||||
fields = (
|
||||
meta.CharField('first_name', maxlength=20),
|
||||
meta.CharField('last_name', maxlength=20),
|
||||
)
|
||||
first_name = meta.CharField(maxlength=20)
|
||||
last_name = meta.CharField(maxlength=20)
|
||||
|
||||
def __repr__(self):
|
||||
return "%s %s" % (self.first_name, self.last_name)
|
||||
|
|
168
tests/testapp/models/subclassing.py
Normal file
168
tests/testapp/models/subclassing.py
Normal file
|
@ -0,0 +1,168 @@
|
|||
"""
|
||||
15. Subclassing models
|
||||
|
||||
You can subclass another model to create a copy of it that behaves slightly
|
||||
differently.
|
||||
"""
|
||||
|
||||
from django.core import meta
|
||||
|
||||
# From the "Bare-bones model" example
|
||||
from django.models.basic import Article
|
||||
|
||||
# From the "Adding __repr__()" example
|
||||
from django.models.repr import Article as ArticleWithRepr
|
||||
|
||||
# From the "Specifying ordering" example
|
||||
from django.models.ordering import Article as ArticleWithOrdering
|
||||
|
||||
# This uses all fields and metadata from Article and
|
||||
# adds a "section" field.
|
||||
class ArticleWithSection(Article):
|
||||
section = meta.CharField(maxlength=30)
|
||||
class META:
|
||||
module_name = 'subarticles1'
|
||||
|
||||
# This uses all fields and metadata from Article but
|
||||
# removes the "pub_date" field.
|
||||
class ArticleWithoutPubDate(Article):
|
||||
class META:
|
||||
module_name = 'subarticles2'
|
||||
remove_fields = ('pub_date',)
|
||||
|
||||
# This uses all fields and metadata from Article but
|
||||
# overrides the "pub_date" field.
|
||||
class ArticleWithFieldOverride(Article):
|
||||
pub_date = meta.DateField() # overrides the old field, a DateTimeField
|
||||
class META:
|
||||
module_name = 'subarticles3'
|
||||
# No need to add remove_fields = ('pub_date',)
|
||||
|
||||
# This uses all fields and metadata from ArticleWithRepr and
|
||||
# makes a few additions/changes.
|
||||
class ArticleWithManyChanges(ArticleWithRepr):
|
||||
section = meta.CharField(maxlength=30)
|
||||
is_popular = meta.BooleanField()
|
||||
pub_date = meta.DateField() # overrides the old field, a DateTimeField
|
||||
class META:
|
||||
module_name = 'subarticles4'
|
||||
|
||||
# This uses all fields from ArticleWithOrdering but
|
||||
# changes the ordering parameter.
|
||||
class ArticleWithChangedMeta(ArticleWithOrdering):
|
||||
class META:
|
||||
module_name = 'subarticles5'
|
||||
ordering = ('headline', 'pub_date')
|
||||
|
||||
API_TESTS = """
|
||||
# No data is in the system yet.
|
||||
>>> subarticles1.get_list()
|
||||
[]
|
||||
>>> subarticles2.get_list()
|
||||
[]
|
||||
>>> subarticles3.get_list()
|
||||
[]
|
||||
|
||||
# Create an ArticleWithSection.
|
||||
>>> from datetime import date, datetime
|
||||
>>> a1 = subarticles1.ArticleWithSection(headline='First', pub_date=datetime(2005, 8, 22), section='News')
|
||||
>>> a1.save()
|
||||
>>> a1
|
||||
<ArticleWithSection object>
|
||||
>>> a1.id
|
||||
1
|
||||
>>> a1.headline
|
||||
'First'
|
||||
>>> a1.pub_date
|
||||
datetime.datetime(2005, 8, 22, 0, 0)
|
||||
|
||||
# Retrieve it again, to prove the fields have been saved.
|
||||
>>> a1 = subarticles1.get_object(pk=1)
|
||||
>>> a1.headline
|
||||
'First'
|
||||
>>> a1.pub_date
|
||||
datetime.datetime(2005, 8, 22, 0, 0)
|
||||
>>> a1.section
|
||||
'News'
|
||||
|
||||
# Create an ArticleWithoutPubDate.
|
||||
>>> a2 = subarticles2.ArticleWithoutPubDate(headline='Second')
|
||||
>>> a2.save()
|
||||
>>> a2
|
||||
<ArticleWithoutPubDate object>
|
||||
>>> a2.id
|
||||
1
|
||||
>>> a2.pub_date
|
||||
Traceback (most recent call last):
|
||||
...
|
||||
AttributeError: 'ArticleWithoutPubDate' object has no attribute 'pub_date'
|
||||
|
||||
# Retrieve it again, to prove the fields have been saved.
|
||||
>>> a2 = subarticles2.get_object(pk=1)
|
||||
>>> a2.headline
|
||||
'Second'
|
||||
>>> a2.pub_date
|
||||
Traceback (most recent call last):
|
||||
...
|
||||
AttributeError: 'ArticleWithoutPubDate' object has no attribute 'pub_date'
|
||||
|
||||
# Create an ArticleWithFieldOverride.
|
||||
>>> a3 = subarticles3.ArticleWithFieldOverride(headline='Third', pub_date=date(2005, 8, 22))
|
||||
>>> a3.save()
|
||||
>>> a3
|
||||
<ArticleWithFieldOverride object>
|
||||
>>> a3.id
|
||||
1
|
||||
>>> a3.pub_date
|
||||
datetime.date(2005, 8, 22)
|
||||
|
||||
# Retrieve it again, to prove the fields have been saved.
|
||||
>>> a3 = subarticles3.get_object(pk=1)
|
||||
>>> a3.headline
|
||||
'Third'
|
||||
>>> a3.pub_date
|
||||
datetime.date(2005, 8, 22)
|
||||
|
||||
# Create an ArticleWithManyChanges.
|
||||
>>> a4 = subarticles4.ArticleWithManyChanges(headline='Fourth', section='Arts',
|
||||
... is_popular=True, pub_date=date(2005, 8, 22))
|
||||
>>> a4.save()
|
||||
|
||||
# a4 inherits __repr__() from its parent model (ArticleWithRepr).
|
||||
>>> a4
|
||||
Fourth
|
||||
|
||||
# Retrieve it again, to prove the fields have been saved.
|
||||
>>> a4 = subarticles4.get_object(pk=1)
|
||||
>>> a4.headline
|
||||
'Fourth'
|
||||
>>> a4.section
|
||||
'Arts'
|
||||
>>> a4.is_popular == True
|
||||
True
|
||||
>>> a4.pub_date
|
||||
datetime.date(2005, 8, 22)
|
||||
|
||||
# Test get_list().
|
||||
>>> subarticles1.get_list()
|
||||
[<ArticleWithSection object>]
|
||||
>>> subarticles2.get_list()
|
||||
[<ArticleWithoutPubDate object>]
|
||||
>>> subarticles3.get_list()
|
||||
[<ArticleWithFieldOverride object>]
|
||||
>>> subarticles4.get_list()
|
||||
[Fourth]
|
||||
|
||||
# Create a couple of ArticleWithChangedMeta objects.
|
||||
>>> a5 = subarticles5.ArticleWithChangedMeta(headline='A', pub_date=datetime(2005, 3, 1))
|
||||
>>> a5.save()
|
||||
>>> a6 = subarticles5.ArticleWithChangedMeta(headline='B', pub_date=datetime(2005, 4, 1))
|
||||
>>> a6.save()
|
||||
>>> a7 = subarticles5.ArticleWithChangedMeta(headline='C', pub_date=datetime(2005, 5, 1))
|
||||
>>> a7.save()
|
||||
|
||||
# Ordering has been overridden, so objects are ordered
|
||||
# by headline ASC instead of pub_date DESC.
|
||||
>>> subarticles5.get_list()
|
||||
[A, B, C]
|
||||
"""
|
Loading…
Add table
Add a link
Reference in a new issue