Changed all model unit tests to use __str__() instead of __repr__(). Also slightly changed related-object DoesNotExist exception message to use repr instead of str
git-svn-id: http://code.djangoproject.com/svn/django/trunk@3075 bcc190cf-cafb-0310-a4f2-bffc1f526a37
This commit is contained in:
parent
55e453a09c
commit
a5b7c29816
|
@ -198,7 +198,7 @@ class ForeignRelatedObjectsDescriptor(object):
|
|||
setattr(obj, rel_field.name, None)
|
||||
obj.save()
|
||||
else:
|
||||
raise rel_field.rel.to.DoesNotExist, "'%s' is not related to '%s'." % (obj, instance)
|
||||
raise rel_field.rel.to.DoesNotExist, "%r is not related to %r." % (obj, instance)
|
||||
remove.alters_data = True
|
||||
|
||||
def clear(self):
|
||||
|
@ -712,7 +712,7 @@ class ManyToManyRel:
|
|||
self.related_name = related_name
|
||||
self.filter_interface = filter_interface
|
||||
if limit_choices_to is None:
|
||||
limit_choices_to = {}
|
||||
limit_choices_to = {}
|
||||
self.limit_choices_to = limit_choices_to
|
||||
self.edit_inline = False
|
||||
self.raw_id_admin = raw_id_admin
|
||||
|
|
|
@ -9,9 +9,10 @@ from django.db import models
|
|||
class Article(models.Model):
|
||||
headline = models.CharField(maxlength=100, default='Default headline')
|
||||
pub_date = models.DateTimeField()
|
||||
|
||||
def __repr__(self):
|
||||
|
||||
def __str__(self):
|
||||
return self.headline
|
||||
|
||||
API_TESTS = """
|
||||
|
||||
# No articles are in the system yet.
|
||||
|
@ -39,34 +40,34 @@ datetime.datetime(2005, 7, 28, 0, 0)
|
|||
>>> a.headline = 'Area woman programs in Python'
|
||||
>>> a.save()
|
||||
|
||||
# Article.objects.all() returns all the articles in the database.
|
||||
# Article.objects.all() returns all the articles in the database.
|
||||
>>> Article.objects.all()
|
||||
[Area woman programs in Python]
|
||||
[<Article: Area woman programs in Python>]
|
||||
|
||||
# Django provides a rich database lookup API.
|
||||
>>> Article.objects.get(id__exact=1)
|
||||
Area woman programs in Python
|
||||
<Article: Area woman programs in Python>
|
||||
>>> Article.objects.get(headline__startswith='Area woman')
|
||||
Area woman programs in Python
|
||||
<Article: Area woman programs in Python>
|
||||
>>> Article.objects.get(pub_date__year=2005)
|
||||
Area woman programs in Python
|
||||
<Article: Area woman programs in Python>
|
||||
>>> Article.objects.get(pub_date__year=2005, pub_date__month=7)
|
||||
Area woman programs in Python
|
||||
<Article: Area woman programs in Python>
|
||||
>>> Article.objects.get(pub_date__year=2005, pub_date__month=7, pub_date__day=28)
|
||||
Area woman programs in Python
|
||||
<Article: Area woman programs in Python>
|
||||
|
||||
# The "__exact" lookup type can be omitted, as a shortcut.
|
||||
>>> Article.objects.get(id=1)
|
||||
Area woman programs in Python
|
||||
<Article: Area woman programs in Python>
|
||||
>>> Article.objects.get(headline='Area woman programs in Python')
|
||||
Area woman programs in Python
|
||||
<Article: Area woman programs in Python>
|
||||
|
||||
>>> Article.objects.filter(pub_date__year=2005)
|
||||
[Area woman programs in Python]
|
||||
[<Article: Area woman programs in Python>]
|
||||
>>> Article.objects.filter(pub_date__year=2004)
|
||||
[]
|
||||
>>> Article.objects.filter(pub_date__year=2005, pub_date__month=7)
|
||||
[Area woman programs in Python]
|
||||
[<Article: Area woman programs in Python>]
|
||||
|
||||
# Django raises an Article.DoesNotExist exception for get() if the parameters
|
||||
# don't match any object.
|
||||
|
@ -84,7 +85,7 @@ DoesNotExist: Article matching query does not exist.
|
|||
# shortcut for primary-key exact lookups.
|
||||
# The following is identical to articles.get(id=1).
|
||||
>>> Article.objects.get(pk=1)
|
||||
Area woman programs in Python
|
||||
<Article: Area woman programs in Python>
|
||||
|
||||
# Model instances of the same type and same ID are considered equal.
|
||||
>>> a = Article.objects.get(pk=1)
|
||||
|
@ -222,7 +223,7 @@ datetime.datetime(2005, 7, 28, 0, 0)
|
|||
>>> s1 = Article.objects.filter(id__exact=1)
|
||||
>>> s2 = Article.objects.filter(id__exact=2)
|
||||
>>> s1 | s2
|
||||
[Area woman programs in Python, Second article]
|
||||
[<Article: Area woman programs in Python>, <Article: Second article>]
|
||||
>>> s1 & s2
|
||||
[]
|
||||
|
||||
|
@ -232,34 +233,34 @@ datetime.datetime(2005, 7, 28, 0, 0)
|
|||
|
||||
# You can get items using index and slice notation.
|
||||
>>> Article.objects.all()[0]
|
||||
Area woman programs in Python
|
||||
<Article: Area woman programs in Python>
|
||||
>>> Article.objects.all()[1:3]
|
||||
[Second article, Third article]
|
||||
[<Article: Second article>, <Article: Third article>]
|
||||
>>> s3 = Article.objects.filter(id__exact=3)
|
||||
>>> (s1 | s2 | s3)[::2]
|
||||
[Area woman programs in Python, Third article]
|
||||
[<Article: Area woman programs in Python>, <Article: Third article>]
|
||||
|
||||
# Slices (without step) are lazy:
|
||||
>>> Article.objects.all()[0:5].filter()
|
||||
[Area woman programs in Python, Second article, Third article, Fourth article, Article 6]
|
||||
[<Article: Area woman programs in Python>, <Article: Second article>, <Article: Third article>, <Article: Fourth article>, <Article: Article 6>]
|
||||
|
||||
# Slicing again works:
|
||||
>>> Article.objects.all()[0:5][0:2]
|
||||
[Area woman programs in Python, Second article]
|
||||
[<Article: Area woman programs in Python>, <Article: Second article>]
|
||||
>>> Article.objects.all()[0:5][:2]
|
||||
[Area woman programs in Python, Second article]
|
||||
[<Article: Area woman programs in Python>, <Article: Second article>]
|
||||
>>> Article.objects.all()[0:5][4:]
|
||||
[Article 6]
|
||||
[<Article: Article 6>]
|
||||
>>> Article.objects.all()[0:5][5:]
|
||||
[]
|
||||
|
||||
# Some more tests!
|
||||
>>> Article.objects.all()[2:][0:2]
|
||||
[Third article, Fourth article]
|
||||
[<Article: Third article>, <Article: Fourth article>]
|
||||
>>> Article.objects.all()[2:][:2]
|
||||
[Third article, Fourth article]
|
||||
[<Article: Third article>, <Article: Fourth article>]
|
||||
>>> Article.objects.all()[2:][2:3]
|
||||
[Article 6]
|
||||
[<Article: Article 6>]
|
||||
|
||||
# Note that you can't use 'offset' without 'limit' (on some dbs), so this doesn't work:
|
||||
>>> Article.objects.all()[2:]
|
||||
|
@ -308,10 +309,10 @@ AttributeError: Manager isn't accessible via Article instances
|
|||
|
||||
# Bulk delete test: How many objects before and after the delete?
|
||||
>>> Article.objects.all()
|
||||
[Area woman programs in Python, Second article, Third article, Fourth article, Article 6, Default headline, Article 7, Updated article 8]
|
||||
[<Article: Area woman programs in Python>, <Article: Second article>, <Article: Third article>, <Article: Fourth article>, <Article: Article 6>, <Article: Default headline>, <Article: Article 7>, <Article: Updated article 8>]
|
||||
>>> Article.objects.filter(id__lte=4).delete()
|
||||
>>> Article.objects.all()
|
||||
[Article 6, Default headline, Article 7, Updated article 8]
|
||||
[<Article: Article 6>, <Article: Default headline>, <Article: Article 7>, <Article: Updated article 8>]
|
||||
|
||||
"""
|
||||
|
||||
|
|
|
@ -20,7 +20,7 @@ class Person(models.Model):
|
|||
name = models.CharField(maxlength=20)
|
||||
gender = models.CharField(maxlength=1, choices=GENDER_CHOICES)
|
||||
|
||||
def __repr__(self):
|
||||
def __str__(self):
|
||||
return self.name
|
||||
|
||||
API_TESTS = """
|
||||
|
|
|
@ -12,7 +12,7 @@ class Person(models.Model):
|
|||
first_name = models.CharField(maxlength=30, db_column='firstname')
|
||||
last_name = models.CharField(maxlength=30, db_column='last')
|
||||
|
||||
def __repr__(self):
|
||||
def __str__(self):
|
||||
return '%s %s' % (self.first_name, self.last_name)
|
||||
|
||||
API_TESTS = """
|
||||
|
@ -24,13 +24,13 @@ API_TESTS = """
|
|||
1
|
||||
|
||||
>>> Person.objects.all()
|
||||
[John Smith]
|
||||
[<Person: John Smith>]
|
||||
|
||||
>>> Person.objects.filter(first_name__exact='John')
|
||||
[John Smith]
|
||||
[<Person: John Smith>]
|
||||
|
||||
>>> Person.objects.get(first_name__exact='John')
|
||||
John Smith
|
||||
<Person: John Smith>
|
||||
|
||||
>>> Person.objects.filter(firstname__exact='John')
|
||||
Traceback (most recent call last):
|
||||
|
|
|
@ -23,7 +23,7 @@ class Person(models.Model):
|
|||
fun = models.BooleanField()
|
||||
objects = PersonManager()
|
||||
|
||||
def __repr__(self):
|
||||
def __str__(self):
|
||||
return "%s %s" % (self.first_name, self.last_name)
|
||||
|
||||
# An example of a custom manager that sets get_query_set().
|
||||
|
@ -39,7 +39,7 @@ class Book(models.Model):
|
|||
published_objects = PublishedBookManager()
|
||||
authors = models.ManyToManyField(Person, related_name='books')
|
||||
|
||||
def __repr__(self):
|
||||
def __str__(self):
|
||||
return self.title
|
||||
|
||||
# An example of providing multiple custom managers.
|
||||
|
@ -55,7 +55,7 @@ class Car(models.Model):
|
|||
cars = models.Manager()
|
||||
fast_cars = FastCarManager()
|
||||
|
||||
def __repr__(self):
|
||||
def __str__(self):
|
||||
return self.name
|
||||
|
||||
API_TESTS = """
|
||||
|
@ -64,7 +64,7 @@ API_TESTS = """
|
|||
>>> p2 = Person(first_name='Droopy', last_name='Dog', fun=False)
|
||||
>>> p2.save()
|
||||
>>> Person.objects.get_fun_people()
|
||||
[Bugs Bunny]
|
||||
[<Person: Bugs Bunny>]
|
||||
|
||||
# The RelatedManager used on the 'books' descriptor extends the default manager
|
||||
>>> from modeltests.custom_managers.models import PublishedBookManager
|
||||
|
@ -89,19 +89,19 @@ AttributeError: type object 'Book' has no attribute 'objects'
|
|||
True
|
||||
|
||||
>>> Book.published_objects.all()
|
||||
[How to program]
|
||||
[<Book: How to program>]
|
||||
|
||||
>>> c1 = Car(name='Corvette', mileage=21, top_speed=180)
|
||||
>>> c1.save()
|
||||
>>> c2 = Car(name='Neon', mileage=31, top_speed=100)
|
||||
>>> c2.save()
|
||||
>>> Car.cars.order_by('name')
|
||||
[Corvette, Neon]
|
||||
[<Car: Corvette>, <Car: Neon>]
|
||||
>>> Car.fast_cars.all()
|
||||
[Corvette]
|
||||
[<Car: Corvette>]
|
||||
|
||||
# Each model class gets a "_default_manager" attribute, which is a reference
|
||||
# to the first manager defined in the class. In this case, it's "cars".
|
||||
>>> Car._default_manager.order_by('name')
|
||||
[Corvette, Neon]
|
||||
[<Car: Corvette>, <Car: Neon>]
|
||||
"""
|
||||
|
|
|
@ -11,16 +11,16 @@ class Article(models.Model):
|
|||
headline = models.CharField(maxlength=100)
|
||||
pub_date = models.DateField()
|
||||
|
||||
def __repr__(self):
|
||||
def __str__(self):
|
||||
return self.headline
|
||||
|
||||
def was_published_today(self):
|
||||
return self.pub_date == datetime.date.today()
|
||||
|
||||
def get_articles_from_same_day_1(self):
|
||||
def articles_from_same_day_1(self):
|
||||
return Article.objects.filter(pub_date=self.pub_date).exclude(id=self.id)
|
||||
|
||||
def get_articles_from_same_day_2(self):
|
||||
def 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.
|
||||
|
@ -47,12 +47,12 @@ API_TESTS = """
|
|||
# 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]
|
||||
>>> a.articles_from_same_day_1()
|
||||
[<Article: Beatles reunite>]
|
||||
>>> a.articles_from_same_day_2()
|
||||
[<Article: Beatles reunite>]
|
||||
>>> b.articles_from_same_day_1()
|
||||
[<Article: Area man programs in Python>]
|
||||
>>> b.articles_from_same_day_2()
|
||||
[<Article: Area man programs in Python>]
|
||||
"""
|
||||
|
|
|
@ -14,7 +14,7 @@ class Employee(models.Model):
|
|||
class Meta:
|
||||
ordering = ('last_name', 'first_name')
|
||||
|
||||
def __repr__(self):
|
||||
def __str__(self):
|
||||
return "%s %s" % (self.first_name, self.last_name)
|
||||
|
||||
class Business(models.Model):
|
||||
|
@ -23,24 +23,24 @@ class Business(models.Model):
|
|||
class Meta:
|
||||
verbose_name_plural = 'businesses'
|
||||
|
||||
def __repr__(self):
|
||||
def __str__(self):
|
||||
return self.name
|
||||
|
||||
API_TESTS = """
|
||||
>>> dan = Employee(employee_code='ABC123', first_name='Dan', last_name='Jones')
|
||||
>>> dan.save()
|
||||
>>> Employee.objects.all()
|
||||
[Dan Jones]
|
||||
[<Employee: Dan Jones>]
|
||||
|
||||
>>> fran = Employee(employee_code='XYZ456', first_name='Fran', last_name='Bones')
|
||||
>>> fran.save()
|
||||
>>> Employee.objects.all()
|
||||
[Fran Bones, Dan Jones]
|
||||
[<Employee: Fran Bones>, <Employee: Dan Jones>]
|
||||
|
||||
>>> Employee.objects.get(pk='ABC123')
|
||||
Dan Jones
|
||||
<Employee: Dan Jones>
|
||||
>>> Employee.objects.get(pk='XYZ456')
|
||||
Fran Bones
|
||||
<Employee: Fran Bones>
|
||||
>>> Employee.objects.get(pk='foo')
|
||||
Traceback (most recent call last):
|
||||
...
|
||||
|
@ -48,43 +48,43 @@ DoesNotExist: Employee matching query does not exist.
|
|||
|
||||
# Use the name of the primary key, rather than pk.
|
||||
>>> Employee.objects.get(employee_code__exact='ABC123')
|
||||
Dan Jones
|
||||
<Employee: Dan Jones>
|
||||
|
||||
# Fran got married and changed her last name.
|
||||
>>> fran = Employee.objects.get(pk='XYZ456')
|
||||
>>> fran.last_name = 'Jones'
|
||||
>>> fran.save()
|
||||
>>> Employee.objects.filter(last_name__exact='Jones')
|
||||
[Dan Jones, Fran Jones]
|
||||
[<Employee: Dan Jones>, <Employee: Fran Jones>]
|
||||
>>> Employee.objects.in_bulk(['ABC123', 'XYZ456'])
|
||||
{'XYZ456': Fran Jones, 'ABC123': Dan Jones}
|
||||
{'XYZ456': <Employee: Fran Jones>, 'ABC123': <Employee: Dan Jones>}
|
||||
|
||||
>>> b = Business(name='Sears')
|
||||
>>> b.save()
|
||||
>>> b.employees.add(dan, fran)
|
||||
>>> b.employees.all()
|
||||
[Dan Jones, Fran Jones]
|
||||
[<Employee: Dan Jones>, <Employee: Fran Jones>]
|
||||
>>> fran.business_set.all()
|
||||
[Sears]
|
||||
[<Business: Sears>]
|
||||
>>> Business.objects.in_bulk(['Sears'])
|
||||
{'Sears': Sears}
|
||||
{'Sears': <Business: Sears>}
|
||||
|
||||
>>> Business.objects.filter(name__exact='Sears')
|
||||
[Sears]
|
||||
[<Business: Sears>]
|
||||
>>> Business.objects.filter(pk='Sears')
|
||||
[Sears]
|
||||
[<Business: Sears>]
|
||||
|
||||
# Queries across tables, involving primary key
|
||||
>>> Employee.objects.filter(business__name__exact='Sears')
|
||||
[Dan Jones, Fran Jones]
|
||||
[<Employee: Dan Jones>, <Employee: Fran Jones>]
|
||||
>>> Employee.objects.filter(business__pk='Sears')
|
||||
[Dan Jones, Fran Jones]
|
||||
[<Employee: Dan Jones>, <Employee: Fran Jones>]
|
||||
|
||||
>>> Business.objects.filter(employees__employee_code__exact='ABC123')
|
||||
[Sears]
|
||||
[<Business: Sears>]
|
||||
>>> Business.objects.filter(employees__pk='ABC123')
|
||||
[Sears]
|
||||
[<Business: Sears>]
|
||||
>>> Business.objects.filter(employees__first_name__startswith='Fran')
|
||||
[Sears]
|
||||
[<Business: Sears>]
|
||||
|
||||
"""
|
||||
|
|
|
@ -17,7 +17,7 @@ class Article(models.Model):
|
|||
class Meta:
|
||||
get_latest_by = 'pub_date'
|
||||
|
||||
def __repr__(self):
|
||||
def __str__(self):
|
||||
return self.headline
|
||||
|
||||
class Person(models.Model):
|
||||
|
@ -26,7 +26,7 @@ class Person(models.Model):
|
|||
|
||||
# Note that this model doesn't have "get_latest_by" set.
|
||||
|
||||
def __repr__(self):
|
||||
def __str__(self):
|
||||
return self.name
|
||||
|
||||
API_TESTS = """
|
||||
|
@ -49,19 +49,19 @@ DoesNotExist: Article matching query does not exist.
|
|||
|
||||
# Get the latest Article.
|
||||
>>> Article.objects.latest()
|
||||
Article 4
|
||||
<Article: Article 4>
|
||||
|
||||
# Get the latest Article that matches certain filters.
|
||||
>>> Article.objects.filter(pub_date__lt=datetime(2005, 7, 27)).latest()
|
||||
Article 1
|
||||
<Article: Article 1>
|
||||
|
||||
# Pass a custom field name to latest() to change the field that's used to
|
||||
# determine the latest object.
|
||||
>>> Article.objects.latest('expire_date')
|
||||
Article 1
|
||||
<Article: Article 1>
|
||||
|
||||
>>> Article.objects.filter(pub_date__gt=datetime(2005, 7, 26)).latest('expire_date')
|
||||
Article 3
|
||||
<Article: Article 3>
|
||||
|
||||
# You can still use latest() with a model that doesn't have "get_latest_by"
|
||||
# set -- just pass in the field name manually.
|
||||
|
@ -75,5 +75,5 @@ Traceback (most recent call last):
|
|||
AssertionError: latest() requires either a field_name parameter or 'get_latest_by' in the model
|
||||
|
||||
>>> Person.objects.latest('birthday')
|
||||
Stephanie
|
||||
<Person: Stephanie>
|
||||
"""
|
||||
|
|
|
@ -12,7 +12,7 @@ class Article(models.Model):
|
|||
class Meta:
|
||||
ordering = ('-pub_date', 'headline')
|
||||
|
||||
def __repr__(self):
|
||||
def __str__(self):
|
||||
return self.headline
|
||||
|
||||
API_TESTS = """
|
||||
|
@ -61,9 +61,9 @@ Article 4
|
|||
# in_bulk() takes a list of IDs and returns a dictionary mapping IDs
|
||||
# to objects.
|
||||
>>> Article.objects.in_bulk([1, 2])
|
||||
{1: Article 1, 2: Article 2}
|
||||
{1: <Article: Article 1>, 2: <Article: Article 2>}
|
||||
>>> Article.objects.in_bulk([3])
|
||||
{3: Article 3}
|
||||
{3: <Article: Article 3>}
|
||||
>>> Article.objects.in_bulk([1000])
|
||||
{}
|
||||
>>> Article.objects.in_bulk([])
|
||||
|
@ -125,55 +125,55 @@ True
|
|||
# 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
|
||||
<Article: Article 2>
|
||||
>>> a2.get_next_by_pub_date()
|
||||
Article 3
|
||||
<Article: Article 3>
|
||||
>>> a3.get_next_by_pub_date()
|
||||
Article 7
|
||||
<Article: Article 7>
|
||||
>>> a4.get_next_by_pub_date()
|
||||
Article 6
|
||||
<Article: Article 6>
|
||||
>>> a5.get_next_by_pub_date()
|
||||
Traceback (most recent call last):
|
||||
...
|
||||
DoesNotExist: Article matching query does not exist.
|
||||
>>> a6.get_next_by_pub_date()
|
||||
Article 5
|
||||
<Article: Article 5>
|
||||
>>> a7.get_next_by_pub_date()
|
||||
Article 4
|
||||
<Article: Article 4>
|
||||
|
||||
>>> a7.get_previous_by_pub_date()
|
||||
Article 3
|
||||
<Article: Article 3>
|
||||
>>> a6.get_previous_by_pub_date()
|
||||
Article 4
|
||||
<Article: Article 4>
|
||||
>>> a5.get_previous_by_pub_date()
|
||||
Article 6
|
||||
<Article: Article 6>
|
||||
>>> a4.get_previous_by_pub_date()
|
||||
Article 7
|
||||
<Article: Article 7>
|
||||
>>> a3.get_previous_by_pub_date()
|
||||
Article 2
|
||||
<Article: Article 2>
|
||||
>>> a2.get_previous_by_pub_date()
|
||||
Article 1
|
||||
<Article: Article 1>
|
||||
|
||||
# Underscores and percent signs have special meaning in the underlying
|
||||
# database library, but Django handles the quoting of them automatically.
|
||||
>>> a8 = Article(headline='Article_ with underscore', pub_date=datetime(2005, 11, 20))
|
||||
>>> a8.save()
|
||||
>>> Article.objects.filter(headline__startswith='Article')
|
||||
[Article_ with underscore, Article 5, Article 6, Article 4, Article 2, Article 3, Article 7, Article 1]
|
||||
[<Article: Article_ with underscore>, <Article: Article 5>, <Article: Article 6>, <Article: Article 4>, <Article: Article 2>, <Article: Article 3>, <Article: Article 7>, <Article: Article 1>]
|
||||
>>> Article.objects.filter(headline__startswith='Article_')
|
||||
[Article_ with underscore]
|
||||
[<Article: Article_ with underscore>]
|
||||
>>> a9 = Article(headline='Article% with percent sign', pub_date=datetime(2005, 11, 21))
|
||||
>>> a9.save()
|
||||
>>> Article.objects.filter(headline__startswith='Article')
|
||||
[Article% with percent sign, Article_ with underscore, Article 5, Article 6, Article 4, Article 2, Article 3, Article 7, Article 1]
|
||||
[<Article: Article% with percent sign>, <Article: Article_ with underscore>, <Article: Article 5>, <Article: Article 6>, <Article: Article 4>, <Article: Article 2>, <Article: Article 3>, <Article: Article 7>, <Article: Article 1>]
|
||||
>>> Article.objects.filter(headline__startswith='Article%')
|
||||
[Article% with percent sign]
|
||||
[<Article: Article% with percent sign>]
|
||||
|
||||
# exclude() is the opposite of filter() when doing lookups:
|
||||
>>> Article.objects.filter(headline__contains='Article').exclude(headline__contains='with')
|
||||
[Article 5, Article 6, Article 4, Article 2, Article 3, Article 7, Article 1]
|
||||
[<Article: Article 5>, <Article: Article 6>, <Article: Article 4>, <Article: Article 2>, <Article: Article 3>, <Article: Article 7>, <Article: Article 1>]
|
||||
>>> Article.objects.exclude(headline__startswith="Article_")
|
||||
[Article% with percent sign, Article 5, Article 6, Article 4, Article 2, Article 3, Article 7, Article 1]
|
||||
[<Article: Article% with percent sign>, <Article: Article 5>, <Article: Article 6>, <Article: Article 4>, <Article: Article 2>, <Article: Article 3>, <Article: Article 7>, <Article: Article 1>]
|
||||
>>> Article.objects.exclude(headline="Article 7")
|
||||
[Article% with percent sign, Article_ with underscore, Article 5, Article 6, Article 4, Article 2, Article 3, Article 1]
|
||||
[<Article: Article% with percent sign>, <Article: Article_ with underscore>, <Article: Article 5>, <Article: Article 6>, <Article: Article 4>, <Article: Article 2>, <Article: Article 3>, <Article: Article 1>]
|
||||
"""
|
||||
|
|
|
@ -16,14 +16,14 @@ class Reporter(models.Model):
|
|||
first_name = models.CharField(maxlength=30)
|
||||
last_name = models.CharField(maxlength=30)
|
||||
|
||||
def __repr__(self):
|
||||
def __str__(self):
|
||||
return "%s %s" % (self.first_name, self.last_name)
|
||||
|
||||
class Article(models.Model):
|
||||
headline = models.CharField(maxlength=100)
|
||||
pub_date = models.DateField()
|
||||
|
||||
def __repr__(self):
|
||||
def __str__(self):
|
||||
return self.headline
|
||||
|
||||
class Writer(models.Model):
|
||||
|
@ -31,8 +31,8 @@ class Writer(models.Model):
|
|||
article = models.ForeignKey(Article)
|
||||
position = models.CharField(maxlength=100)
|
||||
|
||||
def __repr__(self):
|
||||
return '%r (%s)' % (self.reporter, self.position)
|
||||
def __str__(self):
|
||||
return '%s (%s)' % (self.reporter, self.position)
|
||||
|
||||
API_TESTS = """
|
||||
# Create a few Reporters.
|
||||
|
@ -54,15 +54,15 @@ API_TESTS = """
|
|||
|
||||
# Play around with the API.
|
||||
>>> a.writer_set.select_related().order_by('-position')
|
||||
[John Smith (Main writer), Jane Doe (Contributor)]
|
||||
[<Writer: John Smith (Main writer)>, <Writer: Jane Doe (Contributor)>]
|
||||
>>> w1.reporter
|
||||
John Smith
|
||||
<Reporter: John Smith>
|
||||
>>> w2.reporter
|
||||
Jane Doe
|
||||
<Reporter: Jane Doe>
|
||||
>>> w1.article
|
||||
This is a test
|
||||
<Article: This is a test>
|
||||
>>> w2.article
|
||||
This is a test
|
||||
<Article: This is a test>
|
||||
>>> r1.writer_set.all()
|
||||
[John Smith (Main writer)]
|
||||
[<Writer: John Smith (Main writer)>]
|
||||
"""
|
||||
|
|
|
@ -14,7 +14,7 @@ class Category(models.Model):
|
|||
class Meta:
|
||||
ordering = ('name',)
|
||||
|
||||
def __repr__(self):
|
||||
def __str__(self):
|
||||
return self.name
|
||||
|
||||
class Article(models.Model):
|
||||
|
@ -25,7 +25,7 @@ class Article(models.Model):
|
|||
class Meta:
|
||||
ordering = ('pub_date',)
|
||||
|
||||
def __repr__(self):
|
||||
def __str__(self):
|
||||
return self.headline
|
||||
|
||||
API_TESTS = """
|
||||
|
@ -51,29 +51,29 @@ API_TESTS = """
|
|||
>>> a2.secondary_categories.add(c4)
|
||||
|
||||
>>> a1.primary_categories.all()
|
||||
[Crime, News]
|
||||
[<Category: Crime>, <Category: News>]
|
||||
|
||||
>>> a2.primary_categories.all()
|
||||
[News, Sports]
|
||||
[<Category: News>, <Category: Sports>]
|
||||
|
||||
>>> a1.secondary_categories.all()
|
||||
[Life]
|
||||
[<Category: Life>]
|
||||
|
||||
|
||||
>>> c1.primary_article_set.all()
|
||||
[Area man runs]
|
||||
[<Article: Area man runs>]
|
||||
>>> c1.secondary_article_set.all()
|
||||
[]
|
||||
>>> c2.primary_article_set.all()
|
||||
[Area man steals, Area man runs]
|
||||
[<Article: Area man steals>, <Article: Area man runs>]
|
||||
>>> c2.secondary_article_set.all()
|
||||
[]
|
||||
>>> c3.primary_article_set.all()
|
||||
[Area man steals]
|
||||
[<Article: Area man steals>]
|
||||
>>> c3.secondary_article_set.all()
|
||||
[]
|
||||
>>> c4.primary_article_set.all()
|
||||
[]
|
||||
>>> c4.secondary_article_set.all()
|
||||
[Area man steals, Area man runs]
|
||||
[<Article: Area man steals>, <Article: Area man runs>]
|
||||
"""
|
||||
|
|
|
@ -19,7 +19,7 @@ class Person(models.Model):
|
|||
friends = models.ManyToManyField('self')
|
||||
idols = models.ManyToManyField('self', symmetrical=False, related_name='stalkers')
|
||||
|
||||
def __repr__(self):
|
||||
def __str__(self):
|
||||
return self.name
|
||||
|
||||
API_TESTS = """
|
||||
|
@ -41,37 +41,37 @@ API_TESTS = """
|
|||
|
||||
# Who is friends with Anne?
|
||||
>>> a.friends.all()
|
||||
[Bill, Chuck, David]
|
||||
[<Person: Bill>, <Person: Chuck>, <Person: David>]
|
||||
|
||||
# Who is friends with Bill?
|
||||
>>> b.friends.all()
|
||||
[Anne]
|
||||
[<Person: Anne>]
|
||||
|
||||
# Who is friends with Chuck?
|
||||
>>> c.friends.all()
|
||||
[Anne, David]
|
||||
[<Person: Anne>, <Person: David>]
|
||||
|
||||
# Who is friends with David?
|
||||
>>> d.friends.all()
|
||||
[Anne, Chuck]
|
||||
[<Person: Anne>, <Person: Chuck>]
|
||||
|
||||
# Bill is already friends with Anne - add Anne again, but in the reverse direction
|
||||
>>> b.friends.add(a)
|
||||
|
||||
# Who is friends with Anne?
|
||||
>>> a.friends.all()
|
||||
[Bill, Chuck, David]
|
||||
[<Person: Bill>, <Person: Chuck>, <Person: David>]
|
||||
|
||||
# Who is friends with Bill?
|
||||
>>> b.friends.all()
|
||||
[Anne]
|
||||
[<Person: Anne>]
|
||||
|
||||
# Remove Anne from Bill's friends
|
||||
>>> b.friends.remove(a)
|
||||
|
||||
# Who is friends with Anne?
|
||||
>>> a.friends.all()
|
||||
[Chuck, David]
|
||||
[<Person: Chuck>, <Person: David>]
|
||||
|
||||
# Who is friends with Bill?
|
||||
>>> b.friends.all()
|
||||
|
@ -87,11 +87,11 @@ API_TESTS = """
|
|||
# Reverse relationships should also be gone
|
||||
# Who is friends with Chuck?
|
||||
>>> c.friends.all()
|
||||
[David]
|
||||
[<Person: David>]
|
||||
|
||||
# Who is friends with David?
|
||||
>>> d.friends.all()
|
||||
[Chuck]
|
||||
[<Person: Chuck>]
|
||||
|
||||
|
||||
# Add some idols in the direction of field definition
|
||||
|
@ -106,27 +106,27 @@ API_TESTS = """
|
|||
|
||||
# Who are Anne's idols?
|
||||
>>> a.idols.all()
|
||||
[Bill, Chuck, David]
|
||||
[<Person: Bill>, <Person: Chuck>, <Person: David>]
|
||||
|
||||
# Who is stalking Anne?
|
||||
>>> a.stalkers.all()
|
||||
[Bill]
|
||||
[<Person: Bill>]
|
||||
|
||||
# Who are Bill's idols?
|
||||
>>> b.idols.all()
|
||||
[Anne]
|
||||
[<Person: Anne>]
|
||||
|
||||
# Who is stalking Bill?
|
||||
>>> b.stalkers.all()
|
||||
[Anne]
|
||||
[<Person: Anne>]
|
||||
|
||||
# Who are Chuck's idols?
|
||||
>>> c.idols.all()
|
||||
[David]
|
||||
[<Person: David>]
|
||||
|
||||
# Who is stalking Chuck?
|
||||
>>> c.stalkers.all()
|
||||
[Anne]
|
||||
[<Person: Anne>]
|
||||
|
||||
# Who are David's idols?
|
||||
>>> d.idols.all()
|
||||
|
@ -134,40 +134,40 @@ API_TESTS = """
|
|||
|
||||
# Who is stalking David
|
||||
>>> d.stalkers.all()
|
||||
[Anne, Chuck]
|
||||
[<Person: Anne>, <Person: Chuck>]
|
||||
|
||||
# Bill is already being stalked by Anne - add Anne again, but in the reverse direction
|
||||
>>> b.stalkers.add(a)
|
||||
|
||||
# Who are Anne's idols?
|
||||
>>> a.idols.all()
|
||||
[Bill, Chuck, David]
|
||||
[<Person: Bill>, <Person: Chuck>, <Person: David>]
|
||||
|
||||
# Who is stalking Anne?
|
||||
[Bill]
|
||||
[<Person: Bill>]
|
||||
|
||||
# Who are Bill's idols
|
||||
>>> b.idols.all()
|
||||
[Anne]
|
||||
[<Person: Anne>]
|
||||
|
||||
# Who is stalking Bill?
|
||||
>>> b.stalkers.all()
|
||||
[Anne]
|
||||
[<Person: Anne>]
|
||||
|
||||
# Remove Anne from Bill's list of stalkers
|
||||
>>> b.stalkers.remove(a)
|
||||
|
||||
# Who are Anne's idols?
|
||||
>>> a.idols.all()
|
||||
[Chuck, David]
|
||||
[<Person: Chuck>, <Person: David>]
|
||||
|
||||
# Who is stalking Anne?
|
||||
>>> a.stalkers.all()
|
||||
[Bill]
|
||||
[<Person: Bill>]
|
||||
|
||||
# Who are Bill's idols?
|
||||
>>> b.idols.all()
|
||||
[Anne]
|
||||
[<Person: Anne>]
|
||||
|
||||
# Who is stalking Bill?
|
||||
>>> b.stalkers.all()
|
||||
|
@ -187,6 +187,6 @@ API_TESTS = """
|
|||
|
||||
# Who is friends with David?
|
||||
>>> d.stalkers.all()
|
||||
[Chuck]
|
||||
[<Person: Chuck>]
|
||||
|
||||
"""
|
||||
|
|
|
@ -16,7 +16,7 @@ class Category(models.Model):
|
|||
name = models.CharField(maxlength=20)
|
||||
parent = models.ForeignKey('self', null=True, related_name='child_set')
|
||||
|
||||
def __repr__(self):
|
||||
def __str__(self):
|
||||
return self.name
|
||||
|
||||
API_TESTS = """
|
||||
|
@ -27,14 +27,14 @@ API_TESTS = """
|
|||
>>> c.save()
|
||||
|
||||
>>> r.child_set.all()
|
||||
[Child category]
|
||||
[<Category: Child category>]
|
||||
>>> r.child_set.get(name__startswith='Child')
|
||||
Child category
|
||||
<Category: Child category>
|
||||
>>> print r.parent
|
||||
None
|
||||
|
||||
>>> c.child_set.all()
|
||||
[]
|
||||
>>> c.parent
|
||||
Root category
|
||||
<Category: Root category>
|
||||
"""
|
||||
|
|
|
@ -14,7 +14,7 @@ class Person(models.Model):
|
|||
mother = models.ForeignKey('self', null=True, related_name='mothers_child_set')
|
||||
father = models.ForeignKey('self', null=True, related_name='fathers_child_set')
|
||||
|
||||
def __repr__(self):
|
||||
def __str__(self):
|
||||
return self.full_name
|
||||
|
||||
API_TESTS = """
|
||||
|
@ -29,13 +29,13 @@ API_TESTS = """
|
|||
>>> kid.save()
|
||||
|
||||
>>> kid.mother
|
||||
Jane Smith
|
||||
<Person: Jane Smith>
|
||||
>>> kid.father
|
||||
John Smith Senior
|
||||
<Person: John Smith Senior>
|
||||
>>> dad.fathers_child_set.all()
|
||||
[John Smith Junior]
|
||||
[<Person: John Smith Junior>]
|
||||
>>> mom.mothers_child_set.all()
|
||||
[John Smith Junior]
|
||||
[<Person: John Smith Junior>]
|
||||
>>> kid.mothers_child_set.all()
|
||||
[]
|
||||
>>> kid.fathers_child_set.all()
|
||||
|
|
|
@ -10,7 +10,7 @@ class Musician(models.Model):
|
|||
first_name = models.CharField(maxlength=30)
|
||||
last_name = models.CharField(maxlength=30)
|
||||
|
||||
def __repr__(self):
|
||||
def __str__(self):
|
||||
return "%s %s" % (self.first_name, self.last_name)
|
||||
|
||||
class Album(models.Model):
|
||||
|
@ -18,7 +18,7 @@ class Album(models.Model):
|
|||
musician = models.ForeignKey(Musician)
|
||||
release_date = models.DateField(blank=True, null=True)
|
||||
|
||||
def __repr__(self):
|
||||
def __str__(self):
|
||||
return self.name
|
||||
|
||||
API_TESTS = """
|
||||
|
@ -35,7 +35,7 @@ API_TESTS = """
|
|||
|
||||
# Verify it worked.
|
||||
>>> Musician.objects.all()
|
||||
[Ella Fitzgerald]
|
||||
[<Musician: Ella Fitzgerald>]
|
||||
>>> [m1] == list(Musician.objects.all())
|
||||
True
|
||||
|
||||
|
@ -69,9 +69,9 @@ True
|
|||
|
||||
# Verify it worked.
|
||||
>>> Album.objects.all()
|
||||
[Ella and Basie]
|
||||
[<Album: Ella and Basie>]
|
||||
>>> Album.objects.get().musician
|
||||
Ella Fitzgerald
|
||||
<Musician: Ella Fitzgerald>
|
||||
|
||||
# Create an Album with a release_date.
|
||||
>>> data = MultiValueDict({'name': ['Ultimate Ella'], 'musician': ['1'], 'release_date': ['2005-02-13']})
|
||||
|
@ -82,10 +82,10 @@ Ella Fitzgerald
|
|||
|
||||
# Verify it worked.
|
||||
>>> Album.objects.order_by('name')
|
||||
[Ella and Basie, Ultimate Ella]
|
||||
[<Album: Ella and Basie>, <Album: Ultimate Ella>]
|
||||
>>> a2 = Album.objects.get(pk=2)
|
||||
>>> a2
|
||||
Ultimate Ella
|
||||
<Album: Ultimate Ella>
|
||||
>>> a2.release_date
|
||||
datetime.date(2005, 2, 13)
|
||||
"""
|
||||
|
|
|
@ -12,7 +12,7 @@ from django.db import models
|
|||
class Publication(models.Model):
|
||||
title = models.CharField(maxlength=30)
|
||||
|
||||
def __repr__(self):
|
||||
def __str__(self):
|
||||
return self.title
|
||||
|
||||
class Meta:
|
||||
|
@ -22,7 +22,7 @@ class Article(models.Model):
|
|||
headline = models.CharField(maxlength=100)
|
||||
publications = models.ManyToManyField(Publication)
|
||||
|
||||
def __repr__(self):
|
||||
def __str__(self):
|
||||
return self.headline
|
||||
|
||||
class Meta:
|
||||
|
@ -58,29 +58,29 @@ API_TESTS = """
|
|||
|
||||
# Article objects have access to their related Publication objects.
|
||||
>>> a1.publications.all()
|
||||
[The Python Journal]
|
||||
[<Publication: The Python Journal>]
|
||||
>>> a2.publications.all()
|
||||
[Highlights for Children, Science News, Science Weekly, The Python Journal]
|
||||
[<Publication: Highlights for Children>, <Publication: Science News>, <Publication: Science Weekly>, <Publication: The Python Journal>]
|
||||
|
||||
# Publication objects have access to their related Article objects.
|
||||
>>> p2.article_set.all()
|
||||
[NASA uses Python]
|
||||
[<Article: NASA uses Python>]
|
||||
>>> p1.article_set.all()
|
||||
[Django lets you build Web apps easily, NASA uses Python]
|
||||
[<Article: Django lets you build Web apps easily>, <Article: NASA uses Python>]
|
||||
>>> Publication.objects.get(id=4).article_set.all()
|
||||
[NASA uses Python]
|
||||
[<Article: NASA uses Python>]
|
||||
|
||||
# We can perform kwarg queries across m2m relationships
|
||||
>>> Article.objects.filter(publications__id__exact=1)
|
||||
[Django lets you build Web apps easily, NASA uses Python]
|
||||
[<Article: Django lets you build Web apps easily>, <Article: NASA uses Python>]
|
||||
>>> Article.objects.filter(publications__pk=1)
|
||||
[Django lets you build Web apps easily, NASA uses Python]
|
||||
[<Article: Django lets you build Web apps easily>, <Article: NASA uses Python>]
|
||||
|
||||
>>> Article.objects.filter(publications__title__startswith="Science")
|
||||
[NASA uses Python, NASA uses Python]
|
||||
[<Article: NASA uses Python>, <Article: NASA uses Python>]
|
||||
|
||||
>>> Article.objects.filter(publications__title__startswith="Science").distinct()
|
||||
[NASA uses Python]
|
||||
[<Article: NASA uses Python>]
|
||||
|
||||
# The count() function respects distinct() as well.
|
||||
>>> Article.objects.filter(publications__title__startswith="Science").count()
|
||||
|
@ -92,23 +92,23 @@ API_TESTS = """
|
|||
# Reverse m2m queries are supported (i.e., starting at the table that doesn't
|
||||
# have a ManyToManyField).
|
||||
>>> Publication.objects.filter(id__exact=1)
|
||||
[The Python Journal]
|
||||
[<Publication: The Python Journal>]
|
||||
>>> Publication.objects.filter(pk=1)
|
||||
[The Python Journal]
|
||||
[<Publication: The Python Journal>]
|
||||
|
||||
>>> Publication.objects.filter(article__headline__startswith="NASA")
|
||||
[Highlights for Children, Science News, Science Weekly, The Python Journal]
|
||||
[<Publication: Highlights for Children>, <Publication: Science News>, <Publication: Science Weekly>, <Publication: The Python Journal>]
|
||||
|
||||
>>> Publication.objects.filter(article__id__exact=1)
|
||||
[The Python Journal]
|
||||
[<Publication: The Python Journal>]
|
||||
|
||||
>>> Publication.objects.filter(article__pk=1)
|
||||
[The Python Journal]
|
||||
[<Publication: The Python Journal>]
|
||||
|
||||
# If we delete a Publication, its Articles won't be able to access it.
|
||||
>>> p1.delete()
|
||||
>>> Publication.objects.all()
|
||||
[Highlights for Children, Science News, Science Weekly]
|
||||
[<Publication: Highlights for Children>, <Publication: Science News>, <Publication: Science Weekly>]
|
||||
>>> a1 = Article.objects.get(pk=1)
|
||||
>>> a1.publications.all()
|
||||
[]
|
||||
|
@ -116,7 +116,7 @@ API_TESTS = """
|
|||
# If we delete an Article, its Publications won't be able to access it.
|
||||
>>> a2.delete()
|
||||
>>> Article.objects.all()
|
||||
[Django lets you build Web apps easily]
|
||||
[<Article: Django lets you build Web apps easily>]
|
||||
>>> p2.article_set.all()
|
||||
[]
|
||||
|
||||
|
@ -125,22 +125,22 @@ API_TESTS = """
|
|||
>>> a4.save()
|
||||
>>> p2.article_set.add(a4)
|
||||
>>> p2.article_set.all()
|
||||
[NASA finds intelligent life on Earth]
|
||||
[<Article: NASA finds intelligent life on Earth>]
|
||||
>>> a4.publications.all()
|
||||
[Science News]
|
||||
[<Publication: Science News>]
|
||||
|
||||
# Adding via the other end using keywords
|
||||
>>> new_article = p2.article_set.create(headline='Oxygen-free diet works wonders')
|
||||
>>> p2.article_set.all()
|
||||
[NASA finds intelligent life on Earth, Oxygen-free diet works wonders]
|
||||
[<Article: NASA finds intelligent life on Earth>, <Article: Oxygen-free diet works wonders>]
|
||||
>>> a5 = p2.article_set.all()[1]
|
||||
>>> a5.publications.all()
|
||||
[Science News]
|
||||
[<Publication: Science News>]
|
||||
|
||||
# Removing publication from an article:
|
||||
>>> a4.publications.remove(p2)
|
||||
>>> p2.article_set.all()
|
||||
[Oxygen-free diet works wonders]
|
||||
[<Article: Oxygen-free diet works wonders>]
|
||||
>>> a4.publications.all()
|
||||
[]
|
||||
|
||||
|
@ -154,33 +154,33 @@ API_TESTS = """
|
|||
# Relation sets can be assigned. Assignment clears any existing set members
|
||||
>>> p2.article_set = [a4, a5]
|
||||
>>> p2.article_set.all()
|
||||
[NASA finds intelligent life on Earth, Oxygen-free diet works wonders]
|
||||
[<Article: NASA finds intelligent life on Earth>, <Article: Oxygen-free diet works wonders>]
|
||||
>>> a4.publications.all()
|
||||
[Science News]
|
||||
[<Publication: Science News>]
|
||||
>>> a4.publications = [p3]
|
||||
>>> p2.article_set.all()
|
||||
[Oxygen-free diet works wonders]
|
||||
[<Article: Oxygen-free diet works wonders>]
|
||||
>>> a4.publications.all()
|
||||
[Science Weekly]
|
||||
[<Publication: Science Weekly>]
|
||||
|
||||
# Relation sets can be cleared:
|
||||
>>> p2.article_set.clear()
|
||||
>>> p2.article_set.all()
|
||||
[]
|
||||
>>> a4.publications.all()
|
||||
[Science Weekly]
|
||||
[<Publication: Science Weekly>]
|
||||
|
||||
# And you can clear from the other end
|
||||
>>> p2.article_set.add(a4, a5)
|
||||
>>> p2.article_set.all()
|
||||
[NASA finds intelligent life on Earth, Oxygen-free diet works wonders]
|
||||
[<Article: NASA finds intelligent life on Earth>, <Article: Oxygen-free diet works wonders>]
|
||||
>>> a4.publications.all()
|
||||
[Science News, Science Weekly]
|
||||
[<Publication: Science News>, <Publication: Science Weekly>]
|
||||
>>> a4.publications.clear()
|
||||
>>> a4.publications.all()
|
||||
[]
|
||||
>>> p2.article_set.all()
|
||||
[Oxygen-free diet works wonders]
|
||||
[<Article: Oxygen-free diet works wonders>]
|
||||
|
||||
# Recreate the article and Publication we just deleted.
|
||||
>>> p1 = Publication(id=None, title='The Python Journal')
|
||||
|
@ -192,22 +192,22 @@ API_TESTS = """
|
|||
# Bulk delete some Publications - references to deleted publications should go
|
||||
>>> Publication.objects.filter(title__startswith='Science').delete()
|
||||
>>> Publication.objects.all()
|
||||
[Highlights for Children, The Python Journal]
|
||||
[<Publication: Highlights for Children>, <Publication: The Python Journal>]
|
||||
>>> Article.objects.all()
|
||||
[Django lets you build Web apps easily, NASA finds intelligent life on Earth, NASA uses Python, Oxygen-free diet works wonders]
|
||||
[<Article: Django lets you build Web apps easily>, <Article: NASA finds intelligent life on Earth>, <Article: NASA uses Python>, <Article: Oxygen-free diet works wonders>]
|
||||
>>> a2.publications.all()
|
||||
[The Python Journal]
|
||||
[<Publication: The Python Journal>]
|
||||
|
||||
# Bulk delete some articles - references to deleted objects should go
|
||||
>>> q = Article.objects.filter(headline__startswith='Django')
|
||||
>>> print q
|
||||
[Django lets you build Web apps easily]
|
||||
[<Article: Django lets you build Web apps easily>]
|
||||
>>> q.delete()
|
||||
|
||||
# After the delete, the QuerySet cache needs to be cleared, and the referenced objects should be gone
|
||||
>>> print q
|
||||
[]
|
||||
>>> p1.article_set.all()
|
||||
[NASA uses Python]
|
||||
[<Article: NASA uses Python>]
|
||||
|
||||
"""
|
||||
|
|
|
@ -11,7 +11,7 @@ class Reporter(models.Model):
|
|||
last_name = models.CharField(maxlength=30)
|
||||
email = models.EmailField()
|
||||
|
||||
def __repr__(self):
|
||||
def __str__(self):
|
||||
return "%s %s" % (self.first_name, self.last_name)
|
||||
|
||||
class Article(models.Model):
|
||||
|
@ -19,7 +19,7 @@ class Article(models.Model):
|
|||
pub_date = models.DateField()
|
||||
reporter = models.ForeignKey(Reporter)
|
||||
|
||||
def __repr__(self):
|
||||
def __str__(self):
|
||||
return self.headline
|
||||
|
||||
class Meta:
|
||||
|
@ -42,7 +42,7 @@ API_TESTS = """
|
|||
1
|
||||
|
||||
>>> a.reporter
|
||||
John Smith
|
||||
<Reporter: John Smith>
|
||||
|
||||
# Article objects have access to their related Reporter objects.
|
||||
>>> r = a.reporter
|
||||
|
@ -52,7 +52,7 @@ John Smith
|
|||
# Create an Article via the Reporter object.
|
||||
>>> new_article = r.article_set.create(headline="John's second story", pub_date=datetime(2005, 7, 29))
|
||||
>>> new_article
|
||||
John's second story
|
||||
<Article: John's second story>
|
||||
>>> new_article.reporter.id
|
||||
1
|
||||
|
||||
|
@ -62,43 +62,43 @@ John's second story
|
|||
>>> new_article2.reporter.id
|
||||
1
|
||||
>>> r.article_set.all()
|
||||
[John's second story, Paul's story, This is a test]
|
||||
[<Article: John's second story>, <Article: Paul's story>, <Article: This is a test>]
|
||||
|
||||
# Add the same article to a different article set - check that it moves.
|
||||
>>> r2.article_set.add(new_article2)
|
||||
>>> new_article2.reporter.id
|
||||
2
|
||||
>>> r.article_set.all()
|
||||
[John's second story, This is a test]
|
||||
[<Article: John's second story>, <Article: This is a test>]
|
||||
>>> r2.article_set.all()
|
||||
[Paul's story]
|
||||
[<Article: Paul's story>]
|
||||
|
||||
# Assign the article to the reporter directly using the descriptor
|
||||
>>> new_article2.reporter = r
|
||||
>>> new_article2.save()
|
||||
>>> new_article2.reporter
|
||||
John Smith
|
||||
<Reporter: John Smith>
|
||||
>>> new_article2.reporter.id
|
||||
1
|
||||
>>> r.article_set.all()
|
||||
[John's second story, Paul's story, This is a test]
|
||||
[<Article: John's second story>, <Article: Paul's story>, <Article: This is a test>]
|
||||
>>> r2.article_set.all()
|
||||
[]
|
||||
|
||||
# Set the article back again using set descriptor.
|
||||
>>> r2.article_set = [new_article, new_article2]
|
||||
>>> r.article_set.all()
|
||||
[This is a test]
|
||||
[<Article: This is a test>]
|
||||
>>> r2.article_set.all()
|
||||
[John's second story, Paul's story]
|
||||
[<Article: John's second story>, <Article: Paul's story>]
|
||||
|
||||
# Funny case - assignment notation can only go so far; because the
|
||||
# Funny case - assignment notation can only go so far; because the
|
||||
# ForeignKey cannot be null, existing members of the set must remain
|
||||
>>> r.article_set = [new_article]
|
||||
>>> r.article_set.all()
|
||||
[John's second story, This is a test]
|
||||
[<Article: John's second story>, <Article: This is a test>]
|
||||
>>> r2.article_set.all()
|
||||
[Paul's story]
|
||||
[<Article: Paul's story>]
|
||||
|
||||
# Reporter cannot be null - there should not be a clear or remove method
|
||||
>>> hasattr(r2.article_set, 'remove')
|
||||
|
@ -108,10 +108,10 @@ False
|
|||
|
||||
# Reporter objects have access to their related Article objects.
|
||||
>>> r.article_set.all()
|
||||
[John's second story, This is a test]
|
||||
[<Article: John's second story>, <Article: This is a test>]
|
||||
|
||||
>>> r.article_set.filter(headline__startswith='This')
|
||||
[This is a test]
|
||||
[<Article: This is a test>]
|
||||
|
||||
>>> r.article_set.count()
|
||||
2
|
||||
|
@ -121,24 +121,24 @@ False
|
|||
|
||||
# Get articles by id
|
||||
>>> Article.objects.filter(id__exact=1)
|
||||
[This is a test]
|
||||
[<Article: This is a test>]
|
||||
>>> Article.objects.filter(pk=1)
|
||||
[This is a test]
|
||||
[<Article: This is a test>]
|
||||
|
||||
# Query on an article property
|
||||
>>> Article.objects.filter(headline__startswith='This')
|
||||
[This is a test]
|
||||
[<Article: This is a test>]
|
||||
|
||||
# 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".
|
||||
>>> Article.objects.filter(reporter__first_name__exact='John')
|
||||
[John's second story, This is a test]
|
||||
[<Article: John's second story>, <Article: This is a test>]
|
||||
|
||||
# Query twice over the related field.
|
||||
>>> Article.objects.filter(reporter__first_name__exact='John', reporter__last_name__exact='Smith')
|
||||
[John's second story, This is a test]
|
||||
[<Article: John's second story>, <Article: This is a test>]
|
||||
|
||||
# The underlying query only makes one join when a related table is referenced twice.
|
||||
>>> query = Article.objects.filter(reporter__first_name__exact='John', reporter__last_name__exact='Smith')
|
||||
|
@ -148,13 +148,13 @@ False
|
|||
|
||||
# The automatically joined table has a predictable name.
|
||||
>>> Article.objects.filter(reporter__first_name__exact='John').extra(where=["many_to_one_article__reporter.last_name='Smith'"])
|
||||
[John's second story, This is a test]
|
||||
[<Article: John's second story>, <Article: This is a test>]
|
||||
|
||||
# Find all Articles for the Reporter whose ID is 1.
|
||||
>>> Article.objects.filter(reporter__id__exact=1)
|
||||
[John's second story, This is a test]
|
||||
[<Article: John's second story>, <Article: This is a test>]
|
||||
>>> Article.objects.filter(reporter__pk=1)
|
||||
[John's second story, This is a test]
|
||||
[<Article: John's second story>, <Article: This is a test>]
|
||||
|
||||
# You need two underscores between "reporter" and "id" -- not one.
|
||||
>>> Article.objects.filter(reporter_id__exact=1)
|
||||
|
@ -170,7 +170,7 @@ TypeError: Cannot resolve keyword 'reporter_id' into field
|
|||
|
||||
# "pk" shortcut syntax works in a related context, too.
|
||||
>>> Article.objects.filter(reporter__pk=1)
|
||||
[John's second story, This is a test]
|
||||
[<Article: John's second story>, <Article: This is a test>]
|
||||
|
||||
# You can also instantiate an Article by passing
|
||||
# the Reporter's ID instead of a Reporter object.
|
||||
|
@ -179,31 +179,31 @@ TypeError: Cannot resolve keyword 'reporter_id' into field
|
|||
>>> a3.reporter.id
|
||||
1
|
||||
>>> a3.reporter
|
||||
John Smith
|
||||
<Reporter: John Smith>
|
||||
|
||||
# Similarly, the reporter ID can be a string.
|
||||
>>> a4 = Article(id=None, headline="This is a test", pub_date=datetime(2005, 7, 27), reporter_id="1")
|
||||
>>> a4.save()
|
||||
>>> a4.reporter
|
||||
John Smith
|
||||
<Reporter: John Smith>
|
||||
|
||||
# Reporters can be queried
|
||||
>>> Reporter.objects.filter(id__exact=1)
|
||||
[John Smith]
|
||||
[<Reporter: John Smith>]
|
||||
>>> Reporter.objects.filter(pk=1)
|
||||
[John Smith]
|
||||
[<Reporter: John Smith>]
|
||||
>>> Reporter.objects.filter(first_name__startswith='John')
|
||||
[John Smith]
|
||||
[<Reporter: John Smith>]
|
||||
|
||||
# Reporters can query in opposite direction of ForeignKey definition
|
||||
>>> Reporter.objects.filter(article__id__exact=1)
|
||||
[John Smith]
|
||||
[<Reporter: John Smith>]
|
||||
>>> Reporter.objects.filter(article__pk=1)
|
||||
[John Smith]
|
||||
[<Reporter: John Smith>]
|
||||
>>> Reporter.objects.filter(article__headline__startswith='This')
|
||||
[John Smith, John Smith, John Smith]
|
||||
[<Reporter: John Smith>, <Reporter: John Smith>, <Reporter: John Smith>]
|
||||
>>> Reporter.objects.filter(article__headline__startswith='This').distinct()
|
||||
[John Smith]
|
||||
[<Reporter: John Smith>]
|
||||
|
||||
# Counting in the opposite direction works in conjunction with distinct()
|
||||
>>> Reporter.objects.filter(article__headline__startswith='This').count()
|
||||
|
@ -213,20 +213,20 @@ John Smith
|
|||
|
||||
# Queries can go round in circles.
|
||||
>>> Reporter.objects.filter(article__reporter__first_name__startswith='John')
|
||||
[John Smith, John Smith, John Smith, John Smith]
|
||||
[<Reporter: John Smith>, <Reporter: John Smith>, <Reporter: John Smith>, <Reporter: John Smith>]
|
||||
>>> Reporter.objects.filter(article__reporter__first_name__startswith='John').distinct()
|
||||
[John Smith]
|
||||
[<Reporter: John Smith>]
|
||||
|
||||
# If you delete a reporter, his articles will be deleted.
|
||||
>>> Article.objects.all()
|
||||
[John's second story, Paul's story, This is a test, This is a test, This is a test]
|
||||
[<Article: John's second story>, <Article: Paul's story>, <Article: This is a test>, <Article: This is a test>, <Article: This is a test>]
|
||||
>>> Reporter.objects.order_by('first_name')
|
||||
[John Smith, Paul Jones]
|
||||
[<Reporter: John Smith>, <Reporter: Paul Jones>]
|
||||
>>> r2.delete()
|
||||
>>> Article.objects.all()
|
||||
[John's second story, This is a test, This is a test, This is a test]
|
||||
[<Article: John's second story>, <Article: This is a test>, <Article: This is a test>, <Article: This is a test>]
|
||||
>>> Reporter.objects.order_by('first_name')
|
||||
[John Smith]
|
||||
[<Reporter: John Smith>]
|
||||
|
||||
# Deletes using a join in the query
|
||||
>>> Reporter.objects.filter(article__headline__startswith='This').delete()
|
||||
|
|
|
@ -10,19 +10,19 @@ from django.db import models
|
|||
class Reporter(models.Model):
|
||||
name = models.CharField(maxlength=30)
|
||||
|
||||
def __repr__(self):
|
||||
def __str__(self):
|
||||
return self.name
|
||||
|
||||
class Article(models.Model):
|
||||
headline = models.CharField(maxlength=100)
|
||||
reporter = models.ForeignKey(Reporter, null=True)
|
||||
|
||||
def __repr__(self):
|
||||
return self.headline
|
||||
|
||||
class Meta:
|
||||
ordering = ('headline',)
|
||||
|
||||
|
||||
def __str__(self):
|
||||
return self.headline
|
||||
|
||||
API_TESTS = """
|
||||
# Create a Reporter.
|
||||
>>> r = Reporter(name='John Smith')
|
||||
|
@ -36,7 +36,7 @@ API_TESTS = """
|
|||
1
|
||||
|
||||
>>> a.reporter
|
||||
John Smith
|
||||
<Reporter: John Smith>
|
||||
|
||||
# Article objects have access to their related Reporter objects.
|
||||
>>> r = a.reporter
|
||||
|
@ -44,15 +44,15 @@ John Smith
|
|||
# Create an Article via the Reporter object.
|
||||
>>> a2 = r.article_set.create(headline="Second")
|
||||
>>> a2
|
||||
Second
|
||||
<Article: Second>
|
||||
>>> a2.reporter.id
|
||||
1
|
||||
|
||||
# Reporter objects have access to their related Article objects.
|
||||
>>> r.article_set.all()
|
||||
[First, Second]
|
||||
[<Article: First>, <Article: Second>]
|
||||
>>> r.article_set.filter(headline__startswith='Fir')
|
||||
[First]
|
||||
[<Article: First>]
|
||||
>>> r.article_set.count()
|
||||
2
|
||||
|
||||
|
@ -78,47 +78,47 @@ None
|
|||
|
||||
# To retrieve the articles with no reporters set, use "reporter__isnull=True".
|
||||
>>> Article.objects.filter(reporter__isnull=True)
|
||||
[Third]
|
||||
[<Article: Third>]
|
||||
|
||||
# Set the reporter for the Third article
|
||||
>>> r.article_set.add(a3)
|
||||
>>> r.article_set.all()
|
||||
[First, Second, Third]
|
||||
[<Article: First>, <Article: Second>, <Article: Third>]
|
||||
|
||||
# Remove an article from the set, and check that it was removed.
|
||||
>>> r.article_set.remove(a3)
|
||||
>>> r.article_set.all()
|
||||
[First, Second]
|
||||
[<Article: First>, <Article: Second>]
|
||||
>>> Article.objects.filter(reporter__isnull=True)
|
||||
[Third]
|
||||
[<Article: Third>]
|
||||
|
||||
# Create another article and reporter
|
||||
>>> r2 = Reporter(name='Paul Jones')
|
||||
>>> r2.save()
|
||||
>>> a4 = r2.article_set.create(headline='Fourth')
|
||||
>>> r2.article_set.all()
|
||||
[Fourth]
|
||||
[<Article: Fourth>]
|
||||
|
||||
# Try to remove a4 from a set it does not belong to
|
||||
>>> r.article_set.remove(a4)
|
||||
Traceback (most recent call last):
|
||||
...
|
||||
DoesNotExist: 'Article object' is not related to 'Reporter object'.
|
||||
DoesNotExist: <Article: Fourth> is not related to <Reporter: John Smith>.
|
||||
|
||||
>>> r2.article_set.all()
|
||||
[Fourth]
|
||||
[<Article: Fourth>]
|
||||
|
||||
# Use descriptor assignment to allocate ForeignKey. Null is legal, so
|
||||
# existing members of set that are not in the assignment set are set null
|
||||
>>> r2.article_set = [a2, a3]
|
||||
>>> r2.article_set.all()
|
||||
[Second, Third]
|
||||
[<Article: Second>, <Article: Third>]
|
||||
|
||||
# Clear the rest of the set
|
||||
>>> r.article_set.clear()
|
||||
>>> r.article_set.all()
|
||||
[]
|
||||
>>> Article.objects.filter(reporter__isnull=True)
|
||||
[First, Fourth]
|
||||
[<Article: First>, <Article: Fourth>]
|
||||
|
||||
"""
|
||||
|
|
|
@ -10,20 +10,20 @@ class Place(models.Model):
|
|||
name = models.CharField(maxlength=50)
|
||||
address = models.CharField(maxlength=80)
|
||||
|
||||
def __repr__(self):
|
||||
def __str__(self):
|
||||
return "%s the place" % self.name
|
||||
|
||||
class Restaurant(Place):
|
||||
serves_hot_dogs = models.BooleanField()
|
||||
serves_pizza = models.BooleanField()
|
||||
|
||||
def __repr__(self):
|
||||
def __str__(self):
|
||||
return "%s the restaurant" % self.name
|
||||
|
||||
class ItalianRestaurant(Restaurant):
|
||||
serves_gnocchi = models.BooleanField()
|
||||
|
||||
def __repr__(self):
|
||||
def __str__(self):
|
||||
return "%s the italian restaurant" % self.name
|
||||
|
||||
API_TESTS = """
|
||||
|
|
|
@ -12,7 +12,7 @@ class Place(models.Model):
|
|||
name = models.CharField(maxlength=50)
|
||||
address = models.CharField(maxlength=80)
|
||||
|
||||
def __repr__(self):
|
||||
def __str__(self):
|
||||
return "%s the place" % self.name
|
||||
|
||||
class Restaurant(models.Model):
|
||||
|
@ -20,15 +20,15 @@ class Restaurant(models.Model):
|
|||
serves_hot_dogs = models.BooleanField()
|
||||
serves_pizza = models.BooleanField()
|
||||
|
||||
def __repr__(self):
|
||||
def __str__(self):
|
||||
return "%s the restaurant" % self.place.name
|
||||
|
||||
class Waiter(models.Model):
|
||||
restaurant = models.ForeignKey(Restaurant)
|
||||
name = models.CharField(maxlength=50)
|
||||
|
||||
def __repr__(self):
|
||||
return "%s the waiter at %r" % (self.name, self.restaurant)
|
||||
def __str__(self):
|
||||
return "%s the waiter at %s" % (self.name, self.restaurant)
|
||||
|
||||
API_TESTS = """
|
||||
# Create a couple of Places.
|
||||
|
@ -43,11 +43,11 @@ API_TESTS = """
|
|||
|
||||
# A Restaurant can access its place.
|
||||
>>> r.place
|
||||
Demon Dogs the place
|
||||
<Place: Demon Dogs the place>
|
||||
|
||||
# A Place can access its restaurant, if available.
|
||||
>>> p1.restaurant
|
||||
Demon Dogs the restaurant
|
||||
<Restaurant: Demon Dogs the restaurant>
|
||||
|
||||
# p2 doesn't have an associated restaurant.
|
||||
>>> p2.restaurant
|
||||
|
@ -60,69 +60,69 @@ DoesNotExist: Restaurant matching query does not exist.
|
|||
>>> r.place = p2
|
||||
>>> r.save()
|
||||
>>> p2.restaurant
|
||||
Ace Hardware the restaurant
|
||||
<Restaurant: Ace Hardware the restaurant>
|
||||
>>> r.place
|
||||
Ace Hardware the place
|
||||
<Place: Ace Hardware the place>
|
||||
|
||||
# Set the place back again, using assignment in the reverse direction
|
||||
# Need to reget restaurant object first, because the reverse set
|
||||
# Need to reget restaurant object first, because the reverse set
|
||||
# can't update the existing restaurant instance
|
||||
>>> p1.restaurant = r
|
||||
>>> r.save()
|
||||
>>> p1.restaurant
|
||||
Demon Dogs the restaurant
|
||||
<Restaurant: Demon Dogs the restaurant>
|
||||
|
||||
>>> r = Restaurant.objects.get(pk=1)
|
||||
>>> r.place
|
||||
Demon Dogs the place
|
||||
<Place: Demon Dogs the place>
|
||||
|
||||
# Restaurant.objects.all() just returns the Restaurants, not the Places.
|
||||
# Note that there are two restaurants - Ace Hardware the Restaurant was created
|
||||
# in the call to r.place = p2. This means there are multiple restaurants referencing
|
||||
# in the call to r.place = p2. This means there are multiple restaurants referencing
|
||||
# a single place...
|
||||
>>> Restaurant.objects.all()
|
||||
[Demon Dogs the restaurant, Ace Hardware the restaurant]
|
||||
[<Restaurant: Demon Dogs the restaurant>, <Restaurant: Ace Hardware the restaurant>]
|
||||
|
||||
# Place.objects.all() returns all Places, regardless of whether they have
|
||||
# Restaurants.
|
||||
>>> Place.objects.order_by('name')
|
||||
[Ace Hardware the place, Demon Dogs the place]
|
||||
[<Place: Ace Hardware the place>, <Place: Demon Dogs the place>]
|
||||
|
||||
>>> Restaurant.objects.get(place__id__exact=1)
|
||||
Demon Dogs the restaurant
|
||||
<Restaurant: Demon Dogs the restaurant>
|
||||
>>> Restaurant.objects.get(pk=1)
|
||||
Demon Dogs the restaurant
|
||||
<Restaurant: Demon Dogs the restaurant>
|
||||
>>> Restaurant.objects.get(place__exact=1)
|
||||
Demon Dogs the restaurant
|
||||
<Restaurant: Demon Dogs the restaurant>
|
||||
>>> Restaurant.objects.get(place__pk=1)
|
||||
Demon Dogs the restaurant
|
||||
<Restaurant: Demon Dogs the restaurant>
|
||||
>>> Restaurant.objects.get(place__name__startswith="Demon")
|
||||
Demon Dogs the restaurant
|
||||
<Restaurant: Demon Dogs the restaurant>
|
||||
|
||||
>>> Place.objects.get(id__exact=1)
|
||||
Demon Dogs the place
|
||||
<Place: Demon Dogs the place>
|
||||
>>> Place.objects.get(pk=1)
|
||||
Demon Dogs the place
|
||||
<Place: Demon Dogs the place>
|
||||
>>> Place.objects.get(restaurant__place__exact=1)
|
||||
Demon Dogs the place
|
||||
<Place: Demon Dogs the place>
|
||||
>>> Place.objects.get(restaurant__pk=1)
|
||||
Demon Dogs the place
|
||||
<Place: Demon Dogs the place>
|
||||
|
||||
# Add a Waiter to the Restaurant.
|
||||
>>> w = r.waiter_set.create(name='Joe')
|
||||
>>> w.save()
|
||||
>>> w
|
||||
Joe the waiter at Demon Dogs the restaurant
|
||||
<Waiter: Joe the waiter at Demon Dogs the restaurant>
|
||||
|
||||
# Query the waiters
|
||||
>>> Waiter.objects.filter(restaurant__place__exact=1)
|
||||
[Joe the waiter at Demon Dogs the restaurant]
|
||||
[<Waiter: Joe the waiter at Demon Dogs the restaurant>]
|
||||
>>> Waiter.objects.filter(restaurant__pk=1)
|
||||
[Joe the waiter at Demon Dogs the restaurant]
|
||||
[<Waiter: Joe the waiter at Demon Dogs the restaurant>]
|
||||
>>> Waiter.objects.filter(id__exact=1)
|
||||
[Joe the waiter at Demon Dogs the restaurant]
|
||||
[<Waiter: Joe the waiter at Demon Dogs the restaurant>]
|
||||
>>> Waiter.objects.filter(pk=1)
|
||||
[Joe the waiter at Demon Dogs the restaurant]
|
||||
[<Waiter: Joe the waiter at Demon Dogs the restaurant>]
|
||||
|
||||
# Delete the restaurant; the waiter should also be removed
|
||||
>>> r = Restaurant.objects.get(pk=1)
|
||||
|
|
|
@ -1,10 +1,10 @@
|
|||
"""
|
||||
19. OR lookups
|
||||
|
||||
To perform an OR lookup, or a lookup that combines ANDs and ORs,
|
||||
To perform an OR lookup, or a lookup that combines ANDs and ORs,
|
||||
combine QuerySet objects using & and | operators.
|
||||
|
||||
Alternatively, use positional arguments, and pass one or more expressions
|
||||
Alternatively, use positional arguments, and pass one or more expressions
|
||||
of clauses using the variable ``django.db.models.Q`` (or any object with
|
||||
a get_sql method).
|
||||
|
||||
|
@ -16,10 +16,11 @@ from django.db import models
|
|||
class Article(models.Model):
|
||||
headline = models.CharField(maxlength=50)
|
||||
pub_date = models.DateTimeField()
|
||||
|
||||
class Meta:
|
||||
ordering = ('pub_date',)
|
||||
|
||||
def __repr__(self):
|
||||
def __str__(self):
|
||||
return self.headline
|
||||
|
||||
API_TESTS = """
|
||||
|
@ -36,10 +37,10 @@ API_TESTS = """
|
|||
>>> a3.save()
|
||||
|
||||
>>> Article.objects.filter(headline__startswith='Hello') | Article.objects.filter(headline__startswith='Goodbye')
|
||||
[Hello, Goodbye, Hello and goodbye]
|
||||
[<Article: Hello>, <Article: Goodbye>, <Article: Hello and goodbye>]
|
||||
|
||||
>>> Article.objects.filter(Q(headline__startswith='Hello') | Q(headline__startswith='Goodbye'))
|
||||
[Hello, Goodbye, Hello and goodbye]
|
||||
[<Article: Hello>, <Article: Goodbye>, <Article: Hello and goodbye>]
|
||||
|
||||
>>> Article.objects.filter(Q(headline__startswith='Hello') & Q(headline__startswith='Goodbye'))
|
||||
[]
|
||||
|
@ -51,34 +52,34 @@ API_TESTS = """
|
|||
[]
|
||||
|
||||
>>> articles.filter(headline__startswith='Hello') & articles.filter(headline__contains='bye')
|
||||
[Hello and goodbye]
|
||||
[<Article: Hello and goodbye>]
|
||||
|
||||
>>> Article.objects.filter(Q(headline__contains='bye'), headline__startswith='Hello')
|
||||
[Hello and goodbye]
|
||||
[<Article: Hello and goodbye>]
|
||||
|
||||
>>> Article.objects.filter(headline__contains='Hello') | Article.objects.filter(headline__contains='bye')
|
||||
[Hello, Goodbye, Hello and goodbye]
|
||||
[<Article: Hello>, <Article: Goodbye>, <Article: Hello and goodbye>]
|
||||
|
||||
>>> Article.objects.filter(headline__iexact='Hello') | Article.objects.filter(headline__contains='ood')
|
||||
[Hello, Goodbye, Hello and goodbye]
|
||||
[<Article: Hello>, <Article: Goodbye>, <Article: Hello and goodbye>]
|
||||
|
||||
>>> Article.objects.filter(Q(pk=1) | Q(pk=2))
|
||||
[Hello, Goodbye]
|
||||
[<Article: Hello>, <Article: Goodbye>]
|
||||
|
||||
>>> Article.objects.filter(Q(pk=1) | Q(pk=2) | Q(pk=3))
|
||||
[Hello, Goodbye, Hello and goodbye]
|
||||
[<Article: Hello>, <Article: Goodbye>, <Article: Hello and goodbye>]
|
||||
|
||||
# Q arg objects are ANDed
|
||||
# Q arg objects are ANDed
|
||||
>>> Article.objects.filter(Q(headline__startswith='Hello'), Q(headline__contains='bye'))
|
||||
[Hello and goodbye]
|
||||
[<Article: Hello and goodbye>]
|
||||
|
||||
# Q arg AND order is irrelevant
|
||||
>>> Article.objects.filter(Q(headline__contains='bye'), headline__startswith='Hello')
|
||||
[Hello and goodbye]
|
||||
[<Article: Hello and goodbye>]
|
||||
|
||||
# Try some arg queries with operations other than get_list
|
||||
>>> Article.objects.get(Q(headline__startswith='Hello'), Q(headline__contains='bye'))
|
||||
Hello and goodbye
|
||||
<Article: Hello and goodbye>
|
||||
|
||||
>>> Article.objects.filter(Q(headline__startswith='Hello') | Q(headline__contains='bye')).count()
|
||||
3
|
||||
|
@ -87,17 +88,17 @@ Hello and goodbye
|
|||
[{'headline': 'Hello and goodbye', 'pub_date': datetime.datetime(2005, 11, 29, 0, 0), 'id': 3}]
|
||||
|
||||
>>> Article.objects.filter(Q(headline__startswith='Hello')).in_bulk([1,2])
|
||||
{1: Hello}
|
||||
{1: <Article: Hello>}
|
||||
|
||||
# Demonstrating exclude with a Q object
|
||||
>>> Article.objects.exclude(Q(headline__startswith='Hello'))
|
||||
[Goodbye]
|
||||
[<Article: Goodbye>]
|
||||
|
||||
# The 'complex_filter' method supports framework features such as
|
||||
# The 'complex_filter' method supports framework features such as
|
||||
# 'limit_choices_to' which normally take a single dictionary of lookup arguments
|
||||
# but need to support arbitrary queries via Q objects too.
|
||||
>>> Article.objects.complex_filter({'pk': 1})
|
||||
[Hello]
|
||||
[<Article: Hello>]
|
||||
>>> Article.objects.complex_filter(Q(pk=1) | Q(pk=2))
|
||||
[Hello, Goodbye]
|
||||
[<Article: Hello>, <Article: Goodbye>]
|
||||
"""
|
||||
|
|
|
@ -21,7 +21,7 @@ class Article(models.Model):
|
|||
class Meta:
|
||||
ordering = ('-pub_date', 'headline')
|
||||
|
||||
def __repr__(self):
|
||||
def __str__(self):
|
||||
return self.headline
|
||||
|
||||
API_TESTS = """
|
||||
|
@ -39,26 +39,26 @@ API_TESTS = """
|
|||
# By default, Article.objects.all() orders by pub_date descending, then
|
||||
# headline ascending.
|
||||
>>> Article.objects.all()
|
||||
[Article 4, Article 2, Article 3, Article 1]
|
||||
[<Article: Article 4>, <Article: Article 2>, <Article: Article 3>, <Article: Article 1>]
|
||||
|
||||
# Override ordering with order_by, which is in the same format as the ordering
|
||||
# attribute in models.
|
||||
>>> Article.objects.order_by('headline')
|
||||
[Article 1, Article 2, Article 3, Article 4]
|
||||
[<Article: Article 1>, <Article: Article 2>, <Article: Article 3>, <Article: Article 4>]
|
||||
>>> Article.objects.order_by('pub_date', '-headline')
|
||||
[Article 1, Article 3, Article 2, Article 4]
|
||||
[<Article: Article 1>, <Article: Article 3>, <Article: Article 2>, <Article: Article 4>]
|
||||
|
||||
# Use the 'stop' part of slicing notation to limit the results.
|
||||
>>> Article.objects.order_by('headline')[:2]
|
||||
[Article 1, Article 2]
|
||||
[<Article: Article 1>, <Article: Article 2>]
|
||||
|
||||
# Use the 'stop' and 'start' parts of slicing notation to offset the result list.
|
||||
>>> Article.objects.order_by('headline')[1:3]
|
||||
[Article 2, Article 3]
|
||||
[<Article: Article 2>, <Article: Article 3>]
|
||||
|
||||
# Getting a single item should work too:
|
||||
>>> Article.objects.all()[0]
|
||||
Article 4
|
||||
<Article: Article 4>
|
||||
|
||||
# Use '?' to order randomly. (We're using [...] in the output to indicate we
|
||||
# don't know what order the output will be in.
|
||||
|
|
|
@ -12,7 +12,7 @@ class Article(models.Model):
|
|||
headline = models.CharField(maxlength=100, default='Default headline')
|
||||
pub_date = models.DateTimeField()
|
||||
|
||||
def __repr__(self):
|
||||
def __str__(self):
|
||||
return self.headline
|
||||
|
||||
API_TESTS = """
|
||||
|
@ -35,11 +35,11 @@ API_TESTS = """
|
|||
|
||||
# get the first page (zero-based)
|
||||
>>> paginator.get_page(0)
|
||||
[Article 1, Article 2, Article 3, Article 4, Article 5]
|
||||
[<Article: Article 1>, <Article: Article 2>, <Article: Article 3>, <Article: Article 4>, <Article: Article 5>]
|
||||
|
||||
# get the second page
|
||||
>>> paginator.get_page(1)
|
||||
[Article 6, Article 7, Article 8, Article 9]
|
||||
[<Article: Article 6>, <Article: Article 7>, <Article: Article 8>, <Article: Article 9>]
|
||||
|
||||
# does the first page have a next or previous page?
|
||||
>>> paginator.has_next_page(0)
|
||||
|
|
|
@ -21,7 +21,7 @@ class Thing(models.Model):
|
|||
class Meta:
|
||||
db_table = 'select'
|
||||
|
||||
def __repr__(self):
|
||||
def __str__(self):
|
||||
return self.when
|
||||
|
||||
API_TESTS = """
|
||||
|
@ -39,18 +39,18 @@ a
|
|||
h
|
||||
|
||||
>>> Thing.objects.order_by('when')
|
||||
[a, h]
|
||||
[<Thing: a>, <Thing: h>]
|
||||
>>> v = Thing.objects.get(pk='a')
|
||||
>>> print v.join
|
||||
b
|
||||
>>> print v.where
|
||||
2005-01-01
|
||||
>>> Thing.objects.order_by('select.when')
|
||||
[a, h]
|
||||
[<Thing: a>, <Thing: h>]
|
||||
|
||||
>>> Thing.objects.dates('where', 'year')
|
||||
[datetime.datetime(2005, 1, 1, 0, 0), datetime.datetime(2006, 1, 1, 0, 0)]
|
||||
|
||||
>>> Thing.objects.filter(where__month=1)
|
||||
[a]
|
||||
[<Thing: a>]
|
||||
"""
|
||||
|
|
|
@ -8,20 +8,23 @@ from django.db import models
|
|||
|
||||
class User(models.Model):
|
||||
name = models.CharField(maxlength=200)
|
||||
def __repr__(self):
|
||||
|
||||
def __str__(self):
|
||||
return self.name
|
||||
|
||||
class Poll(models.Model):
|
||||
question = models.CharField(maxlength=200)
|
||||
creator = models.ForeignKey(User)
|
||||
def __repr__(self):
|
||||
|
||||
def __str__(self):
|
||||
return self.question
|
||||
|
||||
class Choice(models.Model):
|
||||
name = models.CharField(maxlength=100)
|
||||
poll = models.ForeignKey(Poll, related_name="poll_choice")
|
||||
related_poll = models.ForeignKey(Poll, related_name="related_choice")
|
||||
def __repr(self):
|
||||
|
||||
def __str(self):
|
||||
return self.name
|
||||
|
||||
API_TESTS = """
|
||||
|
@ -38,15 +41,15 @@ API_TESTS = """
|
|||
|
||||
>>> # Reverse lookups by field name:
|
||||
>>> User.objects.get(poll__question__exact="What's the first question?")
|
||||
John Doe
|
||||
<User: John Doe>
|
||||
>>> User.objects.get(poll__question__exact="What's the second question?")
|
||||
Jim Bo
|
||||
<User: Jim Bo>
|
||||
|
||||
>>> # Reverse lookups by related_name:
|
||||
>>> Poll.objects.get(poll_choice__name__exact="This is the answer.")
|
||||
What's the first question?
|
||||
<Poll: What's the first question?>
|
||||
>>> Poll.objects.get(related_choice__name__exact="This is the answer.")
|
||||
What's the second question?
|
||||
<Poll: What's the second question?>
|
||||
|
||||
>>> # If a related_name is given you can't use the field name instead:
|
||||
>>> Poll.objects.get(choice__name__exact="This is the answer")
|
||||
|
|
|
@ -11,7 +11,7 @@ class Person(models.Model):
|
|||
first_name = models.CharField(maxlength=20)
|
||||
last_name = models.CharField(maxlength=20)
|
||||
|
||||
def __repr__(self):
|
||||
def __str__(self):
|
||||
return "%s %s" % (self.first_name, self.last_name)
|
||||
|
||||
def save(self):
|
||||
|
@ -31,7 +31,7 @@ Before save
|
|||
After save
|
||||
|
||||
>>> Person.objects.all()
|
||||
[John Smith]
|
||||
[<Person: John Smith>]
|
||||
|
||||
>>> p1.delete()
|
||||
Before deletion
|
||||
|
|
|
@ -14,7 +14,7 @@ class Reporter(models.Model):
|
|||
last_name = models.CharField(maxlength=30)
|
||||
email = models.EmailField()
|
||||
|
||||
def __repr__(self):
|
||||
def __str__(self):
|
||||
return "%s %s" % (self.first_name, self.last_name)
|
||||
|
||||
API_TESTS = """
|
||||
|
@ -40,7 +40,7 @@ Exception: I meant to do that
|
|||
|
||||
# The object created before the exception still exists
|
||||
>>> Reporter.objects.all()
|
||||
[Alice Smith]
|
||||
[<Reporter: Alice Smith>]
|
||||
|
||||
# the autocommit decorator works exactly the same as the default behavior
|
||||
>>> autocomitted_create_then_fail = transaction.autocommit(create_a_reporter_then_fail)
|
||||
|
@ -51,7 +51,7 @@ Exception: I meant to do that
|
|||
|
||||
# Same behavior as before
|
||||
>>> Reporter.objects.all()
|
||||
[Alice Smith, Ben Jones]
|
||||
[<Reporter: Alice Smith>, <Reporter: Ben Jones>]
|
||||
|
||||
# With the commit_on_success decorator, the transaction is only comitted if the
|
||||
# function doesn't throw an exception
|
||||
|
@ -63,7 +63,7 @@ Exception: I meant to do that
|
|||
|
||||
# This time the object never got saved
|
||||
>>> Reporter.objects.all()
|
||||
[Alice Smith, Ben Jones]
|
||||
[<Reporter: Alice Smith>, <Reporter: Ben Jones>]
|
||||
|
||||
# If there aren't any exceptions, the data will get saved
|
||||
>>> def remove_a_reporter():
|
||||
|
@ -73,7 +73,7 @@ Exception: I meant to do that
|
|||
>>> remove_comitted_on_success = transaction.commit_on_success(remove_a_reporter)
|
||||
>>> remove_comitted_on_success()
|
||||
>>> Reporter.objects.all()
|
||||
[Ben Jones]
|
||||
[<Reporter: Ben Jones>]
|
||||
|
||||
# You can manually manage transactions if you really want to, but you
|
||||
# have to remember to commit/rollback
|
||||
|
@ -84,7 +84,7 @@ Exception: I meant to do that
|
|||
>>> manually_managed = transaction.commit_manually(manually_managed)
|
||||
>>> manually_managed()
|
||||
>>> Reporter.objects.all()
|
||||
[Ben Jones, Carol Doe]
|
||||
[<Reporter: Ben Jones>, <Reporter: Carol Doe>]
|
||||
|
||||
# If you forget, you'll get bad errors
|
||||
>>> def manually_managed_mistake():
|
||||
|
|
|
@ -17,7 +17,7 @@ class Person(models.Model):
|
|||
favorite_moment = models.DateTimeField()
|
||||
email = models.EmailField()
|
||||
|
||||
def __repr__(self):
|
||||
def __str__(self):
|
||||
return self.name
|
||||
|
||||
API_TESTS = """
|
||||
|
|
Loading…
Reference in New Issue