diff options
| author | Adrian Holovaty <adrian@holovaty.com> | 2006-05-02 01:31:56 +0000 |
|---|---|---|
| committer | Adrian Holovaty <adrian@holovaty.com> | 2006-05-02 01:31:56 +0000 |
| commit | f69cf70ed813a8cd7e1f963a14ae39103e8d5265 (patch) | |
| tree | d3b32e84cd66573b3833ddf662af020f8ef2f7a8 /tests/testapp/models | |
| parent | d5dbeaa9be359a4c794885c2e9f1b5a7e5e51fb8 (diff) | |
MERGED MAGIC-REMOVAL BRANCH TO TRUNK. This change is highly backwards-incompatible. Please read http://code.djangoproject.com/wiki/RemovingTheMagic for upgrade instructions.
git-svn-id: http://code.djangoproject.com/svn/django/trunk@2809 bcc190cf-cafb-0310-a4f2-bffc1f526a37
Diffstat (limited to 'tests/testapp/models')
21 files changed, 0 insertions, 1618 deletions
diff --git a/tests/testapp/models/__init__.py b/tests/testapp/models/__init__.py deleted file mode 100644 index a5a41035d6..0000000000 --- a/tests/testapp/models/__init__.py +++ /dev/null @@ -1,5 +0,0 @@ -__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', - 'subclassing', 'many_to_one_null', 'custom_columns', 'reserved_names', - 'or_lookups', 'm2m_multiple'] diff --git a/tests/testapp/models/basic.py b/tests/testapp/models/basic.py deleted file mode 100644 index 7261b8783f..0000000000 --- a/tests/testapp/models/basic.py +++ /dev/null @@ -1,204 +0,0 @@ -""" -1. Bare-bones model - -This is a basic model with only two non-primary-key fields. -""" - -from django.core import meta - -class Article(meta.Model): - headline = meta.CharField(maxlength=100, default='Default headline') - pub_date = meta.DateTimeField() - -API_TESTS = """ -# No articles are in the system yet. ->>> articles.get_list() -[] - -# Create an Article. ->>> from datetime import datetime ->>> a = articles.Article(id=None, headline='Area man programs in Python', -... pub_date=datetime(2005, 7, 28)) - -# Save it into the database. You have to call save() explicitly. ->>> a.save() - -# Now it has an ID. Note it's a long integer, as designated by the trailing "L". ->>> a.id -1L - -# Access database columns via Python attributes. ->>> a.headline -'Area man programs in Python' ->>> a.pub_date -datetime.datetime(2005, 7, 28, 0, 0) - -# Change values by changing the attributes, then calling save(). ->>> a.headline = 'Area woman programs in Python' ->>> a.save() - -# get_list() displays all the articles in the database. Note that the article -# is represented by "<Article object>", because we haven't given the Article -# model a __repr__() method. ->>> articles.get_list() -[<Article object>] - -# Django provides a rich database lookup API that's entirely driven by -# keyword arguments. ->>> articles.get_object(id__exact=1) -<Article object> ->>> articles.get_object(headline__startswith='Area woman') -<Article object> ->>> articles.get_object(pub_date__year=2005) -<Article object> ->>> articles.get_object(pub_date__year=2005, pub_date__month=7) -<Article object> ->>> articles.get_object(pub_date__year=2005, pub_date__month=7, pub_date__day=28) -<Article object> - ->>> articles.get_list(pub_date__year=2005) -[<Article object>] ->>> articles.get_list(pub_date__year=2004) -[] ->>> articles.get_list(pub_date__year=2005, pub_date__month=7) -[<Article object>] - -# Django raises an ArticleDoesNotExist exception for get_object() ->>> articles.get_object(id__exact=2) -Traceback (most recent call last): - ... -ArticleDoesNotExist: Article does not exist for {'order_by': (), 'id__exact': 2} - ->>> articles.get_object(pub_date__year=2005, pub_date__month=8) -Traceback (most recent call last): - ... -ArticleDoesNotExist: Article does not exist for ... - -# Lookup by a primary key is the most common case, so Django provides a -# shortcut for primary-key exact lookups. -# The following is identical to articles.get_object(id__exact=1). ->>> articles.get_object(pk=1) -<Article object> - -# Model instances of the same type and same ID are considered equal. ->>> a = articles.get_object(pk=1) ->>> b = articles.get_object(pk=1) ->>> a == b -True - -# You can initialize a model instance using positional arguments, which should -# match the field order as defined in the model... ->>> a2 = articles.Article(None, 'Second article', datetime(2005, 7, 29)) ->>> a2.save() ->>> a2.id -2L ->>> a2.headline -'Second article' ->>> a2.pub_date -datetime.datetime(2005, 7, 29, 0, 0) - -# ...or, you can use keyword arguments. ->>> a3 = articles.Article(id=None, headline='Third article', -... pub_date=datetime(2005, 7, 30)) ->>> a3.save() ->>> a3.id -3L ->>> a3.headline -'Third article' ->>> a3.pub_date -datetime.datetime(2005, 7, 30, 0, 0) - -# You can also mix and match position and keyword arguments, but be sure not to -# duplicate field information. ->>> a4 = articles.Article(None, 'Fourth article', pub_date=datetime(2005, 7, 31)) ->>> a4.save() ->>> a4.headline -'Fourth article' - -# Don't use invalid keyword arguments. ->>> a5 = articles.Article(id=None, headline='Invalid', pub_date=datetime(2005, 7, 31), foo='bar') -Traceback (most recent call last): - ... -TypeError: 'foo' is an invalid keyword argument for this function - -# You can leave off the ID. ->>> a5 = articles.Article(headline='Article 6', pub_date=datetime(2005, 7, 31)) ->>> a5.save() ->>> a5.id -5L ->>> a5.headline -'Article 6' - -# If you leave off a field with "default" set, Django will use the default. ->>> a6 = articles.Article(pub_date=datetime(2005, 7, 31)) ->>> a6.save() ->>> a6.headline -'Default headline' - -# For DateTimeFields, Django saves as much precision (in seconds) as you -# give it. ->>> a7 = articles.Article(headline='Article 7', pub_date=datetime(2005, 7, 31, 12, 30)) ->>> a7.save() ->>> articles.get_object(id__exact=7).pub_date -datetime.datetime(2005, 7, 31, 12, 30) - ->>> a8 = articles.Article(headline='Article 8', pub_date=datetime(2005, 7, 31, 12, 30, 45)) ->>> a8.save() ->>> articles.get_object(id__exact=8).pub_date -datetime.datetime(2005, 7, 31, 12, 30, 45) ->>> a8.id -8L - -# Saving an object again shouldn't create a new object -- it just saves the old one. ->>> a8.save() ->>> a8.id -8L ->>> a8.headline = 'Updated article 8' ->>> a8.save() ->>> a8.id -8L - ->>> a7 == a8 -False ->>> a8 == articles.get_object(id__exact=8) -True ->>> a7 != a8 -True ->>> articles.get_object(id__exact=8) != articles.get_object(id__exact=7) -True ->>> articles.get_object(id__exact=8) == articles.get_object(id__exact=7) -False -""" - -from django.conf import settings - -building_docs = getattr(settings, 'BUILDING_DOCS', False) - -if building_docs or settings.DATABASE_ENGINE == 'postgresql': - API_TESTS += """ -# In PostgreSQL, microsecond-level precision is available. ->>> a9 = articles.Article(headline='Article 9', pub_date=datetime(2005, 7, 31, 12, 30, 45, 180)) ->>> a9.save() ->>> articles.get_object(id__exact=9).pub_date -datetime.datetime(2005, 7, 31, 12, 30, 45, 180) -""" - -if building_docs or settings.DATABASE_ENGINE == 'mysql': - API_TESTS += """ -# In MySQL, microsecond-level precision isn't available. You'll lose -# microsecond-level precision once the data is saved. ->>> a9 = articles.Article(headline='Article 9', pub_date=datetime(2005, 7, 31, 12, 30, 45, 180)) ->>> a9.save() ->>> articles.get_object(id__exact=9).pub_date -datetime.datetime(2005, 7, 31, 12, 30, 45) -""" - -API_TESTS += """ - -# You can manually specify the primary key when creating a new object ->>> a101 = articles.Article(id=101, headline='Article 101', pub_date=datetime(2005, 7, 31, 12, 30, 45)) ->>> a101.save() ->>> a101 = articles.get_object(pk=101) ->>> a101.headline -'Article 101' -""" diff --git a/tests/testapp/models/custom_columns.py b/tests/testapp/models/custom_columns.py deleted file mode 100644 index c900091b64..0000000000 --- a/tests/testapp/models/custom_columns.py +++ /dev/null @@ -1,53 +0,0 @@ -""" -17. Custom column names - -If your database column name is different than your model attribute, use the -``db_column`` parameter. Note that you'll use the field's name, not its column -name, in API usage. -""" - -from django.core import meta - -class Person(meta.Model): - first_name = meta.CharField(maxlength=30, db_column='firstname') - last_name = meta.CharField(maxlength=30, db_column='last') - - def __repr__(self): - return '%s %s' % (self.first_name, self.last_name) - -API_TESTS = """ -# Create a Person. ->>> p = persons.Person(first_name='John', last_name='Smith') ->>> p.save() - ->>> p.id -1 - ->>> persons.get_list() -[John Smith] - ->>> persons.get_list(first_name__exact='John') -[John Smith] - ->>> persons.get_object(first_name__exact='John') -John Smith - ->>> persons.get_list(firstname__exact='John') -Traceback (most recent call last): - ... -TypeError: got unexpected keyword argument 'firstname__exact' - ->>> p = persons.get_object(last_name__exact='Smith') ->>> p.first_name -'John' ->>> p.last_name -'Smith' ->>> p.firstname -Traceback (most recent call last): - ... -AttributeError: 'Person' object has no attribute 'firstname' ->>> p.last -Traceback (most recent call last): - ... -AttributeError: 'Person' object has no attribute 'last' -""" diff --git a/tests/testapp/models/custom_methods.py b/tests/testapp/models/custom_methods.py deleted file mode 100644 index 4f175752b4..0000000000 --- a/tests/testapp/models/custom_methods.py +++ /dev/null @@ -1,72 +0,0 @@ -""" -3. Giving models custom methods and custom module-level functions - -Any method you add to a model will be available to instances. - -Custom methods have the same namespace as if the model class were defined -in the dynamically-generated module. That is, methods can access -``get_list()``, ``get_object()``, ``AddManipulator``, and all other -module-level objects. - -Also, custom methods have access to a few commonly-used objects for -convenience: - - * The ``datetime`` module from Python's standard library. - * The ``db`` object from ``django.core.db``. This represents the database - connection, so you can do custom queries via a cursor object. - -If your model method starts with "_module_", it'll be a module-level function -instead of a method. Otherwise, custom module-level functions have the same -namespace as custom methods. -""" - -from django.core import meta - -class Article(meta.Model): - headline = meta.CharField(maxlength=100) - pub_date = meta.DateField() - - def __repr__(self): - return self.headline - - def was_published_today(self): - return self.pub_date == datetime.date.today() - - def get_articles_from_same_day_1(self): - return get_list(id__ne=self.id, pub_date__exact=self.pub_date) - - def get_articles_from_same_day_2(self): - """ - Verbose version of get_articles_from_same_day_1, which does a custom - database query for the sake of demonstration. - """ - cursor = db.cursor() - cursor.execute(""" - SELECT id, headline, pub_date - FROM custom_methods_articles - WHERE pub_date = %s - AND id != %s""", [str(self.pub_date), self.id]) - # The asterisk in "Article(*row)" tells Python to expand the list into - # positional arguments to Article(). - return [Article(*row) for row in cursor.fetchall()] - -API_TESTS = """ -# Create a couple of Articles. ->>> from datetime import date ->>> a = articles.Article(id=None, headline='Area man programs in Python', pub_date=date(2005, 7, 27)) ->>> a.save() ->>> b = articles.Article(id=None, headline='Beatles reunite', pub_date=date(2005, 7, 27)) ->>> b.save() - -# Test the custom methods. ->>> a.was_published_today() -False ->>> a.get_articles_from_same_day_1() -[Beatles reunite] ->>> a.get_articles_from_same_day_2() -[Beatles reunite] ->>> b.get_articles_from_same_day_1() -[Area man programs in Python] ->>> b.get_articles_from_same_day_2() -[Area man programs in Python] -""" diff --git a/tests/testapp/models/custom_pk.py b/tests/testapp/models/custom_pk.py deleted file mode 100644 index 24041d64cd..0000000000 --- a/tests/testapp/models/custom_pk.py +++ /dev/null @@ -1,69 +0,0 @@ -""" -14. Using a custom primary key - -By default, Django adds an ``"id"`` field to each model. But you can override -this behavior by explicitly adding ``primary_key=True`` to a field. -""" - -from django.core import meta - -class Employee(meta.Model): - 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) - -class Business(meta.Model): - name = meta.CharField(maxlength=20, primary_key=True) - employees = meta.ManyToManyField(Employee) - class META: - verbose_name_plural = 'businesses' - module_name = 'businesses' - - def __repr__(self): - return self.name - -API_TESTS = """ ->>> dan = employees.Employee(employee_code='ABC123', first_name='Dan', last_name='Jones') ->>> dan.save() ->>> employees.get_list() -[Dan Jones] - ->>> fran = employees.Employee(employee_code='XYZ456', first_name='Fran', last_name='Bones') ->>> fran.save() ->>> employees.get_list() -[Fran Bones, Dan Jones] - ->>> employees.get_object(pk='ABC123') -Dan Jones ->>> employees.get_object(pk='XYZ456') -Fran Bones ->>> employees.get_object(pk='foo') -Traceback (most recent call last): - ... -EmployeeDoesNotExist: Employee does not exist for {'pk': 'foo', 'order_by': ()} - -# Fran got married and changed her last name. ->>> fran = employees.get_object(pk='XYZ456') ->>> fran.last_name = 'Jones' ->>> fran.save() ->>> employees.get_list(last_name__exact='Jones') -[Dan Jones, Fran Jones] ->>> employees.get_in_bulk(['ABC123', 'XYZ456']) -{'XYZ456': Fran Jones, 'ABC123': Dan Jones} - ->>> b = businesses.Business(name='Sears') ->>> b.save() ->>> b.set_employees([dan.employee_code, fran.employee_code]) -True ->>> b.get_employee_list() -[Dan Jones, Fran Jones] ->>> fran.get_business_list() -[Sears] ->>> businesses.get_in_bulk(['Sears']) -{'Sears': Sears} -""" diff --git a/tests/testapp/models/get_latest.py b/tests/testapp/models/get_latest.py deleted file mode 100644 index 86697e85a7..0000000000 --- a/tests/testapp/models/get_latest.py +++ /dev/null @@ -1,43 +0,0 @@ -""" -8. get_latest_by - -Models can have a ``get_latest_by`` attribute, which should be set to the name -of a DateField or DateTimeField. If ``get_latest_by`` exists, the model's -module will get a ``get_latest()`` function, which will return the latest -object in the database according to that field. "Latest" means "having the -date farthest into the future." -""" - -from django.core import meta - -class Article(meta.Model): - headline = meta.CharField(maxlength=100) - pub_date = meta.DateTimeField() - class META: - get_latest_by = 'pub_date' - - def __repr__(self): - return self.headline - -API_TESTS = """ -# Because no Articles exist yet, get_latest() raises ArticleDoesNotExist. ->>> articles.get_latest() -Traceback (most recent call last): - ... -ArticleDoesNotExist: Article does not exist for {'order_by': ('-pub_date',), 'limit': 1} - -# Create a couple of Articles. ->>> from datetime import datetime ->>> a1 = articles.Article(id=None, 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.save() ->>> a3 = articles.Article(id=None, 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.save() - -# Get the latest Article. ->>> articles.get_latest() -Article 4 -""" diff --git a/tests/testapp/models/lookup.py b/tests/testapp/models/lookup.py deleted file mode 100644 index 03f5c7ff71..0000000000 --- a/tests/testapp/models/lookup.py +++ /dev/null @@ -1,153 +0,0 @@ -""" -7. The lookup API - -This demonstrates features of the database API. -""" - -from django.core import meta - -class Article(meta.Model): - headline = meta.CharField(maxlength=100) - pub_date = meta.DateTimeField() - class META: - ordering = ('-pub_date', 'headline') - - def __repr__(self): - return self.headline - -API_TESTS = """ -# Create a couple of Articles. ->>> from datetime import datetime ->>> a1 = articles.Article(headline='Article 1', pub_date=datetime(2005, 7, 26)) ->>> a1.save() ->>> a2 = articles.Article(headline='Article 2', pub_date=datetime(2005, 7, 27)) ->>> a2.save() ->>> a3 = articles.Article(headline='Article 3', pub_date=datetime(2005, 7, 27)) ->>> a3.save() ->>> a4 = articles.Article(headline='Article 4', pub_date=datetime(2005, 7, 28)) ->>> a4.save() ->>> a5 = articles.Article(headline='Article 5', pub_date=datetime(2005, 8, 1, 9, 0)) ->>> a5.save() ->>> a6 = articles.Article(headline='Article 6', pub_date=datetime(2005, 8, 1, 8, 0)) ->>> a6.save() ->>> a7 = articles.Article(headline='Article 7', pub_date=datetime(2005, 7, 27)) ->>> a7.save() - -# get_iterator() is just like get_list(), but it's a generator. ->>> for a in articles.get_iterator(): -... print a.headline -Article 5 -Article 6 -Article 4 -Article 2 -Article 3 -Article 7 -Article 1 - -# get_iterator() takes the same lookup arguments as get_list(). ->>> for a in articles.get_iterator(headline__endswith='4'): -... print a.headline -Article 4 - -# get_count() returns the number of objects matching search criteria. ->>> articles.get_count() -7L ->>> articles.get_count(pub_date__exact=datetime(2005, 7, 27)) -3L ->>> articles.get_count(headline__startswith='Blah blah') -0L - -# get_in_bulk() takes a list of IDs and returns a dictionary mapping IDs -# to objects. ->>> articles.get_in_bulk([1, 2]) -{1: Article 1, 2: Article 2} ->>> articles.get_in_bulk([3]) -{3: Article 3} ->>> articles.get_in_bulk([1000]) -{} ->>> articles.get_in_bulk([]) -Traceback (most recent call last): - ... -AssertionError: get_in_bulk() cannot be passed an empty list. - -# get_values() is just like get_list(), except it returns a list of -# dictionaries instead of object instances -- and you can specify which fields -# you want to retrieve. ->>> articles.get_values(fields=['headline']) -[{'headline': 'Article 5'}, {'headline': 'Article 6'}, {'headline': 'Article 4'}, {'headline': 'Article 2'}, {'headline': 'Article 3'}, {'headline': 'Article 7'}, {'headline': 'Article 1'}] ->>> articles.get_values(pub_date__exact=datetime(2005, 7, 27), fields=['id']) -[{'id': 2}, {'id': 3}, {'id': 7}] ->>> articles.get_values(fields=['id', 'headline']) == [{'id': 5, 'headline': 'Article 5'}, {'id': 6, 'headline': 'Article 6'}, {'id': 4, 'headline': 'Article 4'}, {'id': 2, 'headline': 'Article 2'}, {'id': 3, 'headline': 'Article 3'}, {'id': 7, 'headline': 'Article 7'}, {'id': 1, 'headline': 'Article 1'}] -True - -# get_values_iterator() is just like get_values(), but it's a generator. ->>> for d in articles.get_values_iterator(fields=['id', 'headline']): -... i = d.items() -... i.sort() -... i -[('headline', 'Article 5'), ('id', 5)] -[('headline', 'Article 6'), ('id', 6)] -[('headline', 'Article 4'), ('id', 4)] -[('headline', 'Article 2'), ('id', 2)] -[('headline', 'Article 3'), ('id', 3)] -[('headline', 'Article 7'), ('id', 7)] -[('headline', 'Article 1'), ('id', 1)] - -# Every DateField and DateTimeField creates get_next_by_FOO() and -# get_previous_by_FOO() methods. -# In the case of identical date values, these methods will use the ID as a -# fallback check. This guarantees that no records are skipped or duplicated. ->>> a1.get_next_by_pub_date() -Article 2 ->>> a2.get_next_by_pub_date() -Article 3 ->>> a3.get_next_by_pub_date() -Article 7 ->>> a4.get_next_by_pub_date() -Article 6 ->>> a5.get_next_by_pub_date() -Traceback (most recent call last): - ... -ArticleDoesNotExist: Article does not exist for ... ->>> a6.get_next_by_pub_date() -Article 5 ->>> a7.get_next_by_pub_date() -Article 4 - ->>> a7.get_previous_by_pub_date() -Article 3 ->>> a6.get_previous_by_pub_date() -Article 4 ->>> a5.get_previous_by_pub_date() -Article 6 ->>> a4.get_previous_by_pub_date() -Article 7 ->>> a3.get_previous_by_pub_date() -Article 2 ->>> a2.get_previous_by_pub_date() -Article 1 - -# Every DateField and DateTimeField give their model module a get_FOO_list -# function. ->>> articles.get_pub_date_list('year') -[datetime.datetime(2005, 1, 1, 0, 0)] ->>> articles.get_pub_date_list('month') -[datetime.datetime(2005, 7, 1, 0, 0), datetime.datetime(2005, 8, 1, 0, 0)] ->>> articles.get_pub_date_list('day') -[datetime.datetime(2005, 7, 26, 0, 0), datetime.datetime(2005, 7, 27, 0, 0), datetime.datetime(2005, 7, 28, 0, 0), datetime.datetime(2005, 8, 1, 0, 0)] - -# Underscores and percent signs have special meaning in the underlying -# database library, but Django handles the quoting of them automatically. ->>> a8 = articles.Article(headline='Article_ with underscore', pub_date=datetime(2005, 11, 20)) ->>> a8.save() ->>> articles.get_list(headline__startswith='Article') -[Article_ with underscore, Article 5, Article 6, Article 4, Article 2, Article 3, Article 7, Article 1] ->>> articles.get_list(headline__startswith='Article_') -[Article_ with underscore] ->>> a9 = articles.Article(headline='Article% with percent sign', pub_date=datetime(2005, 11, 21)) ->>> a9.save() ->>> articles.get_list(headline__startswith='Article') -[Article% with percent sign, Article_ with underscore, Article 5, Article 6, Article 4, Article 2, Article 3, Article 7, Article 1] ->>> articles.get_list(headline__startswith='Article%') -[Article% with percent sign] -""" diff --git a/tests/testapp/models/m2m_intermediary.py b/tests/testapp/models/m2m_intermediary.py deleted file mode 100644 index 2a20072e03..0000000000 --- a/tests/testapp/models/m2m_intermediary.py +++ /dev/null @@ -1,68 +0,0 @@ -""" -9. Many-to-many relationships via an intermediary table - -For many-to-many relationships that need extra fields on the intermediary -table, use an intermediary model. - -In this example, an ``Article`` can have multiple ``Reporter``s, and each -``Article``-``Reporter`` combination (a ``Writer``) has a ``position`` field, -which specifies the ``Reporter``'s position for the given article (e.g. "Staff -writer"). -""" - -from django.core import meta - -class Reporter(meta.Model): - 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): - headline = meta.CharField(maxlength=100) - pub_date = meta.DateField() - - def __repr__(self): - return self.headline - -class Writer(meta.Model): - 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(first_name='John', last_name='Smith') ->>> r1.save() ->>> r2 = reporters.Reporter(first_name='Jane', last_name='Doe') ->>> r2.save() - -# Create an Article. ->>> from datetime import datetime ->>> a = articles.Article(headline='This is a test', pub_date=datetime(2005, 7, 27)) ->>> a.save() - -# Create a few Writers. ->>> w1 = writers.Writer(reporter=r1, article=a, position='Main writer') ->>> w1.save() ->>> w2 = writers.Writer(reporter=r2, article=a, position='Contributor') ->>> w2.save() - -# Play around with the API. ->>> a.get_writer_list(order_by=['-position'], select_related=True) -[John Smith (Main writer), Jane Doe (Contributor)] ->>> w1.get_reporter() -John Smith ->>> w2.get_reporter() -Jane Doe ->>> w1.get_article() -This is a test ->>> w2.get_article() -This is a test ->>> r1.get_writer_list() -[John Smith (Main writer)] -""" diff --git a/tests/testapp/models/m2m_multiple.py b/tests/testapp/models/m2m_multiple.py deleted file mode 100644 index d8793acb73..0000000000 --- a/tests/testapp/models/m2m_multiple.py +++ /dev/null @@ -1,99 +0,0 @@ -""" -20. Multiple many-to-many relationships between the same two tables - -In this example, an Article can have many Categories (as "primary") and many -Categories (as "secondary"). - -Set ``related_name`` to designate what the reverse relationship is called. - -Set ``singular`` to designate what the category object is called. This is -required if a model has multiple ``ManyToManyFields`` to the same object. -""" - -from django.core import meta - -class Category(meta.Model): - name = meta.CharField(maxlength=20) - class META: - module_name = 'categories' - ordering = ('name',) - - def __repr__(self): - return self.name - -class Article(meta.Model): - headline = meta.CharField(maxlength=50) - pub_date = meta.DateTimeField() - primary_categories = meta.ManyToManyField(Category, - singular='primary_category', related_name='primary_article') - secondary_categories = meta.ManyToManyField(Category, - singular='secondary_category', related_name='secondary_article') - class META: - ordering = ('pub_date',) - - def __repr__(self): - return self.headline - -API_TESTS = """ ->>> from datetime import datetime - ->>> c1 = categories.Category(name='Sports') ->>> c1.save() ->>> c2 = categories.Category(name='News') ->>> c2.save() ->>> c3 = categories.Category(name='Crime') ->>> c3.save() ->>> c4 = categories.Category(name='Life') ->>> c4.save() - ->>> a1 = articles.Article(headline='Area man steals', pub_date=datetime(2005, 11, 27)) ->>> a1.save() ->>> a1.set_primary_categories([c2.id, c3.id]) -True ->>> a1.set_secondary_categories([c4.id]) -True - ->>> a2 = articles.Article(headline='Area man runs', pub_date=datetime(2005, 11, 28)) ->>> a2.save() ->>> a2.set_primary_categories([c1.id, c2.id]) -True ->>> a2.set_secondary_categories([c4.id]) -True - -# The "primary_category" here comes from the "singular" parameter. If we hadn't -# specified the "singular" parameter, Django would just use "category", which -# would cause a conflict because the "primary_categories" and -# "secondary_categories" fields both relate to Category. ->>> a1.get_primary_category_list() -[Crime, News] - -# Ditto for the "primary_category" here. ->>> a2.get_primary_category_list() -[News, Sports] - -# Ditto for the "secondary_category" here. ->>> a1.get_secondary_category_list() -[Life] - -# Ditto for the "secondary_category" here. ->>> a2.get_secondary_category_list() -[Life] - - ->>> c1.get_primary_article_list() -[Area man runs] ->>> c1.get_secondary_article_list() -[] ->>> c2.get_primary_article_list() -[Area man steals, Area man runs] ->>> c2.get_secondary_article_list() -[] ->>> c3.get_primary_article_list() -[Area man steals] ->>> c3.get_secondary_article_list() -[] ->>> c4.get_primary_article_list() -[] ->>> c4.get_secondary_article_list() -[Area man steals, Area man runs] -""" diff --git a/tests/testapp/models/m2o_recursive.py b/tests/testapp/models/m2o_recursive.py deleted file mode 100644 index 27d13b4e7e..0000000000 --- a/tests/testapp/models/m2o_recursive.py +++ /dev/null @@ -1,44 +0,0 @@ -""" -11. Relating an object to itself, many-to-one - -To define a many-to-one relationship between a model and itself, use -``ForeignKey('self')``. - -In this example, a ``Category`` is related to itself. That is, each -``Category`` has a parent ``Category``. - -Set ``related_name`` to designate what the reverse relationship is called. -""" - -from django.core import meta - -class Category(meta.Model): - 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=None) ->>> r.save() ->>> c = categories.Category(id=None, name='Child category', parent=r) ->>> c.save() - ->>> r.get_child_list() -[Child category] ->>> r.get_child(name__startswith='Child') -Child category ->>> r.get_parent() -Traceback (most recent call last): - ... -CategoryDoesNotExist - ->>> c.get_child_list() -[] ->>> c.get_parent() -Root category -""" diff --git a/tests/testapp/models/m2o_recursive2.py b/tests/testapp/models/m2o_recursive2.py deleted file mode 100644 index 52aa0f8b69..0000000000 --- a/tests/testapp/models/m2o_recursive2.py +++ /dev/null @@ -1,43 +0,0 @@ -""" -12. Relating a model to another model more than once - -In this example, a ``Person`` can have a ``mother`` and ``father`` -- both of -which are other ``Person`` objects. - -Set ``related_name`` to designate what the reverse relationship is called. -""" - -from django.core import meta - -class Person(meta.Model): - 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(full_name='John Smith Senior', mother=None, father=None) ->>> dad.save() ->>> mom = persons.Person(full_name='Jane Smith', mother=None, father=None) ->>> mom.save() - -# Give mom and dad a kid. ->>> kid = persons.Person(full_name='John Smith Junior', mother=mom, father=dad) ->>> kid.save() - ->>> kid.get_mother() -Jane Smith ->>> kid.get_father() -John Smith Senior ->>> dad.get_fathers_child_list() -[John Smith Junior] ->>> mom.get_mothers_child_list() -[John Smith Junior] ->>> kid.get_mothers_child_list() -[] ->>> kid.get_fathers_child_list() -[] -""" diff --git a/tests/testapp/models/many_to_many.py b/tests/testapp/models/many_to_many.py deleted file mode 100644 index 91addafe9b..0000000000 --- a/tests/testapp/models/many_to_many.py +++ /dev/null @@ -1,82 +0,0 @@ -""" -5. Many-to-many relationships - -To define a many-to-many relationship, use ManyToManyField(). - -In this example, an article can be published in multiple publications, -and a publication has multiple articles. -""" - -from django.core import meta - -class Publication(meta.Model): - title = meta.CharField(maxlength=30) - - def __repr__(self): - return self.title - -class Article(meta.Model): - headline = meta.CharField(maxlength=100) - publications = meta.ManyToManyField(Publication) - - def __repr__(self): - return self.headline - -API_TESTS = """ -# Create a couple of Publications. ->>> p1 = publications.Publication(id=None, title='The Python Journal') ->>> p1.save() ->>> p2 = publications.Publication(id=None, title='Science News') ->>> p2.save() - -# Create an Article. ->>> a1 = articles.Article(id=None, headline='Django lets you build Web apps easily') ->>> a1.save() - -# Associate the Article with one Publication. set_publications() returns a -# boolean, representing whether any records were added or deleted. ->>> a1.set_publications([p1.id]) -True - -# If we set it again, it'll return False, because the list of Publications -# hasn't changed. ->>> a1.set_publications([p1.id]) -False - -# Create another Article, and set it to appear in both Publications. ->>> a2 = articles.Article(id=None, headline='NASA uses Python') ->>> a2.save() ->>> a2.set_publications([p1.id, p2.id]) -True ->>> a2.set_publications([p1.id]) -True ->>> a2.set_publications([p1.id, p2.id]) -True - -# Article objects have access to their related Publication objects. ->>> a1.get_publication_list() -[The Python Journal] ->>> a2.get_publication_list() -[The Python Journal, Science News] - -# Publication objects have access to their related Article objects. ->>> p2.get_article_list() -[NASA uses Python] ->>> p1.get_article_list(order_by=['headline']) -[Django lets you build Web apps easily, NASA uses Python] - -# If we delete a Publication, its Articles won't be able to access it. ->>> p1.delete() ->>> publications.get_list() -[Science News] ->>> a1 = articles.get_object(pk=1) ->>> a1.get_publication_list() -[] - -# If we delete an Article, its Publications won't be able to access it. ->>> a2.delete() ->>> articles.get_list() -[Django lets you build Web apps easily] ->>> p1.get_article_list(order_by=['headline']) -[Django lets you build Web apps easily] -""" diff --git a/tests/testapp/models/many_to_one.py b/tests/testapp/models/many_to_one.py deleted file mode 100644 index 37828b6d82..0000000000 --- a/tests/testapp/models/many_to_one.py +++ /dev/null @@ -1,98 +0,0 @@ -""" -4. Many-to-one relationships - -To define a many-to-one relationship, use ``ForeignKey()`` . -""" - -from django.core import meta - -class Reporter(meta.Model): - first_name = meta.CharField(maxlength=30) - last_name = meta.CharField(maxlength=30) - email = meta.EmailField() - - def __repr__(self): - return "%s %s" % (self.first_name, self.last_name) - -class Article(meta.Model): - 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(first_name='John', last_name='Smith', email='john@example.com') ->>> 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=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() ->>> r.first_name, r.last_name -('John', 'Smith') - -# Create an Article via the Reporter object. ->>> 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 -1 - -# Reporter objects have access to their related Article objects. ->>> r.get_article_list(order_by=['pub_date']) -[This is a test, John's second story] - ->>> r.get_article(headline__startswith='This') -This is a test - ->>> r.get_article_count() -2 - -# The API automatically follows relationships as far as you need. -# Use double underscores to separate relationships. -# This works as many levels deep as you want. There's no limit. -# Find all Articles for any Reporter whose first name is "John". ->>> 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 -""" diff --git a/tests/testapp/models/many_to_one_null.py b/tests/testapp/models/many_to_one_null.py deleted file mode 100644 index c3c92601f7..0000000000 --- a/tests/testapp/models/many_to_one_null.py +++ /dev/null @@ -1,78 +0,0 @@ -""" -16. Many-to-one relationships that can be null - -To define a many-to-one relationship that can have a null foreign key, 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] -""" diff --git a/tests/testapp/models/one_to_one.py b/tests/testapp/models/one_to_one.py deleted file mode 100644 index b5d749c25d..0000000000 --- a/tests/testapp/models/one_to_one.py +++ /dev/null @@ -1,80 +0,0 @@ -""" -10. One-to-one relationships - -To define a one-to-one relationship, use ``OneToOneField()``. - -In this example, a ``Place`` optionally can be a ``Restaurant``. -""" - -from django.core import meta - -class Place(meta.Model): - name = meta.CharField(maxlength=50) - address = meta.CharField(maxlength=80) - - def __repr__(self): - return "%s the place" % self.name - -class Restaurant(meta.Model): - place = meta.OneToOneField(Place) - serves_hot_dogs = meta.BooleanField() - serves_pizza = meta.BooleanField() - - def __repr__(self): - return "%s the restaurant" % self.get_place().name - -class Waiter(meta.Model): - restaurant = meta.ForeignKey(Restaurant) - name = meta.CharField(maxlength=50) - - def __repr__(self): - return "%s the waiter at %r" % (self.name, self.get_restaurant()) - -API_TESTS = """ -# Create a couple of Places. ->>> p1 = places.Place(name='Demon Dogs', address='944 W. Fullerton') ->>> p1.save() ->>> 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(place=p1, serves_hot_dogs=True, serves_pizza=False) ->>> r.save() - -# A Restaurant can access its place. ->>> r.get_place() -Demon Dogs the place - -# A Place can access its restaurant, if available. ->>> p1.get_restaurant() -Demon Dogs the restaurant - -# p2 doesn't have an associated restaurant. ->>> p2.get_restaurant() -Traceback (most recent call last): - ... -RestaurantDoesNotExist: Restaurant does not exist for {'order_by': (), 'place__id__exact': ...} - -# restaurants.get_list() just returns the Restaurants, not the Places. ->>> restaurants.get_list() -[Demon Dogs the restaurant] - -# places.get_list() returns all Places, regardless of whether they have -# 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 - -# Add a Waiter to the Restaurant. ->>> w = r.add_waiter(name='Joe') ->>> w.save() ->>> w -Joe the waiter at Demon Dogs the restaurant - ->>> r = restaurants.get_object(pk=1) ->>> r.delete() -""" diff --git a/tests/testapp/models/or_lookups.py b/tests/testapp/models/or_lookups.py deleted file mode 100644 index 0bf554e408..0000000000 --- a/tests/testapp/models/or_lookups.py +++ /dev/null @@ -1,57 +0,0 @@ -""" -19. OR lookups - -To perform an OR lookup, or a lookup that combines ANDs and ORs, use the -``complex`` keyword argument, and pass it an expression of clauses using the -variable ``django.core.meta.Q``. -""" - -from django.core import meta - -class Article(meta.Model): - headline = meta.CharField(maxlength=50) - pub_date = meta.DateTimeField() - class META: - ordering = ('pub_date',) - - def __repr__(self): - return self.headline - -API_TESTS = """ ->>> from datetime import datetime ->>> from django.core.meta import Q - ->>> a1 = articles.Article(headline='Hello', pub_date=datetime(2005, 11, 27)) ->>> a1.save() - ->>> a2 = articles.Article(headline='Goodbye', pub_date=datetime(2005, 11, 28)) ->>> a2.save() - ->>> a3 = articles.Article(headline='Hello and goodbye', pub_date=datetime(2005, 11, 29)) ->>> a3.save() - ->>> articles.get_list(complex=(Q(headline__startswith='Hello') | Q(headline__startswith='Goodbye'))) -[Hello, Goodbye, Hello and goodbye] - ->>> articles.get_list(complex=(Q(headline__startswith='Hello') & Q(headline__startswith='Goodbye'))) -[] - ->>> articles.get_list(complex=(Q(headline__startswith='Hello') & Q(headline__contains='bye'))) -[Hello and goodbye] - ->>> articles.get_list(headline__startswith='Hello', complex=Q(headline__contains='bye')) -[Hello and goodbye] - ->>> articles.get_list(complex=(Q(headline__contains='Hello') | Q(headline__contains='bye'))) -[Hello, Goodbye, Hello and goodbye] - ->>> articles.get_list(complex=(Q(headline__iexact='Hello') | Q(headline__contains='ood'))) -[Hello, Goodbye, Hello and goodbye] - ->>> articles.get_list(complex=(Q(pk=1) | Q(pk=2))) -[Hello, Goodbye] - ->>> articles.get_list(complex=(Q(pk=1) | Q(pk=2) | Q(pk=3))) -[Hello, Goodbye, Hello and goodbye] - -""" diff --git a/tests/testapp/models/ordering.py b/tests/testapp/models/ordering.py deleted file mode 100644 index 6256e4daf7..0000000000 --- a/tests/testapp/models/ordering.py +++ /dev/null @@ -1,63 +0,0 @@ -""" -6. Specifying ordering - -Specify default ordering for a model using the ``ordering`` attribute, which -should be a list or tuple of field names. This tells Django how to order the -results of ``get_list()`` and other similar functions. - -If a field name in ``ordering`` starts with a hyphen, that field will be -ordered in descending order. Otherwise, it'll be ordered in ascending order. -The special-case field name ``"?"`` specifies random order. - -The ordering attribute is not required. If you leave it off, ordering will be -undefined -- not random, just undefined. -""" - -from django.core import meta - -class Article(meta.Model): - headline = meta.CharField(maxlength=100) - pub_date = meta.DateTimeField() - class META: - ordering = ('-pub_date', 'headline') - - def __repr__(self): - return self.headline - -API_TESTS = """ -# Create a couple of Articles. ->>> from datetime import datetime ->>> a1 = articles.Article(headline='Article 1', pub_date=datetime(2005, 7, 26)) ->>> a1.save() ->>> a2 = articles.Article(headline='Article 2', pub_date=datetime(2005, 7, 27)) ->>> a2.save() ->>> a3 = articles.Article(headline='Article 3', pub_date=datetime(2005, 7, 27)) ->>> a3.save() ->>> 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 -# headline ascending. ->>> articles.get_list() -[Article 4, Article 2, Article 3, Article 1] - -# Override ordering with order_by, which is in the same format as the ordering -# attribute in models. ->>> articles.get_list(order_by=['headline']) -[Article 1, Article 2, Article 3, Article 4] ->>> articles.get_list(order_by=['pub_date', '-headline']) -[Article 1, Article 3, Article 2, Article 4] - -# Use the "limit" parameter to limit the results. ->>> articles.get_list(order_by=['headline'], limit=2) -[Article 1, Article 2] - -# Use the "offset" parameter with "limit" to offset the result list. ->>> articles.get_list(order_by=['headline'], offset=1, limit=2) -[Article 2, Article 3] - -# Use '?' to order randomly. (We're using [...] in the output to indicate we -# don't know what order the output will be in. ->>> articles.get_list(order_by=['?']) -[...] -""" diff --git a/tests/testapp/models/repr.py b/tests/testapp/models/repr.py deleted file mode 100644 index 3d4daf22c9..0000000000 --- a/tests/testapp/models/repr.py +++ /dev/null @@ -1,31 +0,0 @@ -""" -2. Adding __repr__() to models - -Although it's not a strict requirement, each model should have a ``__repr__()`` -method to return a "human-readable" representation of the object. Do this not -only for your own sanity when dealing with the interactive prompt, but also -because objects' representations are used throughout Django's -automatically-generated admin. -""" - -from django.core import meta - -class Article(meta.Model): - headline = meta.CharField(maxlength=100) - pub_date = meta.DateTimeField() - - def __repr__(self): - return self.headline - -API_TESTS = """ -# Create an Article. ->>> from datetime import datetime ->>> a = articles.Article(headline='Area man programs in Python', pub_date=datetime(2005, 7, 28)) ->>> a.save() - ->>> repr(a) -'Area man programs in Python' - ->>> a -Area man programs in Python -""" diff --git a/tests/testapp/models/reserved_names.py b/tests/testapp/models/reserved_names.py deleted file mode 100644 index eabe41e5bd..0000000000 --- a/tests/testapp/models/reserved_names.py +++ /dev/null @@ -1,47 +0,0 @@ -""" -18. Using SQL reserved names - -Need to use a reserved SQL name as a column name or table name? Need to include -a hyphen in a column or table name? No problem. Django quotes names -appropriately behind the scenes, so your database won't complain about -reserved-name usage. -""" - -from django.core import meta - -class Thing(meta.Model): - when = meta.CharField(maxlength=1, primary_key=True) - join = meta.CharField(maxlength=1) - like = meta.CharField(maxlength=1) - drop = meta.CharField(maxlength=1) - alter = meta.CharField(maxlength=1) - having = meta.CharField(maxlength=1) - where = meta.CharField(maxlength=1) - has_hyphen = meta.CharField(maxlength=1, db_column='has-hyphen') - class META: - db_table = 'select' - - def __repr__(self): - return self.when - -API_TESTS = """ ->>> t = things.Thing(when='a', join='b', like='c', drop='d', alter='e', having='f', where='g', has_hyphen='h') ->>> t.save() ->>> print t.when -a - ->>> u = things.Thing(when='h', join='i', like='j', drop='k', alter='l', having='m', where='n') ->>> u.save() ->>> print u.when -h - ->>> things.get_list(order_by=['when']) -[a, h] ->>> v = things.get_object(pk='a') ->>> print v.join -b ->>> print v.where -g ->>> things.get_list(order_by=['select.when']) -[a, h] -""" diff --git a/tests/testapp/models/save_delete_hooks.py b/tests/testapp/models/save_delete_hooks.py deleted file mode 100644 index f0fa836f71..0000000000 --- a/tests/testapp/models/save_delete_hooks.py +++ /dev/null @@ -1,49 +0,0 @@ -""" -13. Adding hooks before/after saving and deleting - -Django provides hooks for executing arbitrary code around ``save()`` and -``delete()``. Just add any of the following methods to your model: - - * ``_pre_save()`` is called before an object is saved. - * ``_post_save()`` is called after an object is saved. - * ``_pre_delete()`` is called before an object is deleted. - * ``_post_delete()`` is called after an object is deleted. -""" - -from django.core import meta - -class Person(meta.Model): - first_name = meta.CharField(maxlength=20) - last_name = meta.CharField(maxlength=20) - - def __repr__(self): - return "%s %s" % (self.first_name, self.last_name) - - def _pre_save(self): - print "Before save" - - def _post_save(self): - print "After save" - - def _pre_delete(self): - print "Before deletion" - - def _post_delete(self): - print "After deletion" - -API_TESTS = """ ->>> p1 = persons.Person(first_name='John', last_name='Smith') ->>> p1.save() -Before save -After save - ->>> persons.get_list() -[John Smith] - ->>> p1.delete() -Before deletion -After deletion - ->>> persons.get_list() -[] -""" diff --git a/tests/testapp/models/subclassing.py b/tests/testapp/models/subclassing.py deleted file mode 100644 index e0dad26acb..0000000000 --- a/tests/testapp/models/subclassing.py +++ /dev/null @@ -1,180 +0,0 @@ -""" -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') - -# These two models don't define a module_name. -class NoModuleNameFirst(Article): - section = meta.CharField(maxlength=30) - -class NoModuleNameSecond(Article): - section = meta.CharField(maxlength=30) - -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] - ->>> nomodulenamefirsts.get_list() -[] ->>> nomodulenameseconds.get_list() -[] -""" |
