thirdparty/google_appengine/lib/django/tests/modeltests/lookup/models.py
changeset 109 620f9b141567
equal deleted inserted replaced
108:261778de26ff 109:620f9b141567
       
     1 """
       
     2 7. The lookup API
       
     3 
       
     4 This demonstrates features of the database API.
       
     5 """
       
     6 
       
     7 from django.db import models
       
     8 
       
     9 class Article(models.Model):
       
    10     headline = models.CharField(maxlength=100)
       
    11     pub_date = models.DateTimeField()
       
    12     class Meta:
       
    13         ordering = ('-pub_date', 'headline')
       
    14 
       
    15     def __str__(self):
       
    16         return self.headline
       
    17 
       
    18 __test__ = {'API_TESTS':r"""
       
    19 # Create a couple of Articles.
       
    20 >>> from datetime import datetime
       
    21 >>> a1 = Article(headline='Article 1', pub_date=datetime(2005, 7, 26))
       
    22 >>> a1.save()
       
    23 >>> a2 = Article(headline='Article 2', pub_date=datetime(2005, 7, 27))
       
    24 >>> a2.save()
       
    25 >>> a3 = Article(headline='Article 3', pub_date=datetime(2005, 7, 27))
       
    26 >>> a3.save()
       
    27 >>> a4 = Article(headline='Article 4', pub_date=datetime(2005, 7, 28))
       
    28 >>> a4.save()
       
    29 >>> a5 = Article(headline='Article 5', pub_date=datetime(2005, 8, 1, 9, 0))
       
    30 >>> a5.save()
       
    31 >>> a6 = Article(headline='Article 6', pub_date=datetime(2005, 8, 1, 8, 0))
       
    32 >>> a6.save()
       
    33 >>> a7 = Article(headline='Article 7', pub_date=datetime(2005, 7, 27))
       
    34 >>> a7.save()
       
    35 
       
    36 # Each QuerySet gets iterator(), which is a generator that "lazily" returns
       
    37 # results using database-level iteration.
       
    38 >>> for a in Article.objects.iterator():
       
    39 ...     print a.headline
       
    40 Article 5
       
    41 Article 6
       
    42 Article 4
       
    43 Article 2
       
    44 Article 3
       
    45 Article 7
       
    46 Article 1
       
    47 
       
    48 # iterator() can be used on any QuerySet.
       
    49 >>> for a in Article.objects.filter(headline__endswith='4').iterator():
       
    50 ...     print a.headline
       
    51 Article 4
       
    52 
       
    53 # count() returns the number of objects matching search criteria.
       
    54 >>> Article.objects.count()
       
    55 7L
       
    56 >>> Article.objects.filter(pub_date__exact=datetime(2005, 7, 27)).count()
       
    57 3L
       
    58 >>> Article.objects.filter(headline__startswith='Blah blah').count()
       
    59 0L
       
    60 
       
    61 # count() should respect sliced query sets.
       
    62 >>> articles = Article.objects.all()
       
    63 >>> articles.count()
       
    64 7L
       
    65 >>> articles[:4].count()
       
    66 4
       
    67 >>> articles[1:100].count()
       
    68 6L
       
    69 >>> articles[10:100].count()
       
    70 0
       
    71 
       
    72 # Date and date/time lookups can also be done with strings.
       
    73 >>> Article.objects.filter(pub_date__exact='2005-07-27 00:00:00').count()
       
    74 3L
       
    75 
       
    76 # in_bulk() takes a list of IDs and returns a dictionary mapping IDs
       
    77 # to objects.
       
    78 >>> Article.objects.in_bulk([1, 2])
       
    79 {1: <Article: Article 1>, 2: <Article: Article 2>}
       
    80 >>> Article.objects.in_bulk([3])
       
    81 {3: <Article: Article 3>}
       
    82 >>> Article.objects.in_bulk([1000])
       
    83 {}
       
    84 >>> Article.objects.in_bulk([])
       
    85 {}
       
    86 >>> Article.objects.in_bulk('foo')
       
    87 Traceback (most recent call last):
       
    88     ...
       
    89 AssertionError: in_bulk() must be provided with a list of IDs.
       
    90 >>> Article.objects.in_bulk()
       
    91 Traceback (most recent call last):
       
    92     ...
       
    93 TypeError: in_bulk() takes exactly 2 arguments (1 given)
       
    94 >>> Article.objects.in_bulk(headline__startswith='Blah')
       
    95 Traceback (most recent call last):
       
    96     ...
       
    97 TypeError: in_bulk() got an unexpected keyword argument 'headline__startswith'
       
    98 
       
    99 # values() returns a list of dictionaries instead of object instances -- and
       
   100 # you can specify which fields you want to retrieve.
       
   101 >>> Article.objects.values('headline')
       
   102 [{'headline': 'Article 5'}, {'headline': 'Article 6'}, {'headline': 'Article 4'}, {'headline': 'Article 2'}, {'headline': 'Article 3'}, {'headline': 'Article 7'}, {'headline': 'Article 1'}]
       
   103 >>> Article.objects.filter(pub_date__exact=datetime(2005, 7, 27)).values('id')
       
   104 [{'id': 2}, {'id': 3}, {'id': 7}]
       
   105 >>> list(Article.objects.values('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'}]
       
   106 True
       
   107 
       
   108 >>> for d in Article.objects.values('id', 'headline'):
       
   109 ...     i = d.items()
       
   110 ...     i.sort()
       
   111 ...     i
       
   112 [('headline', 'Article 5'), ('id', 5)]
       
   113 [('headline', 'Article 6'), ('id', 6)]
       
   114 [('headline', 'Article 4'), ('id', 4)]
       
   115 [('headline', 'Article 2'), ('id', 2)]
       
   116 [('headline', 'Article 3'), ('id', 3)]
       
   117 [('headline', 'Article 7'), ('id', 7)]
       
   118 [('headline', 'Article 1'), ('id', 1)]
       
   119 
       
   120 # You can use values() with iterator() for memory savings, because iterator()
       
   121 # uses database-level iteration.
       
   122 >>> for d in Article.objects.values('id', 'headline').iterator():
       
   123 ...     i = d.items()
       
   124 ...     i.sort()
       
   125 ...     i
       
   126 [('headline', 'Article 5'), ('id', 5)]
       
   127 [('headline', 'Article 6'), ('id', 6)]
       
   128 [('headline', 'Article 4'), ('id', 4)]
       
   129 [('headline', 'Article 2'), ('id', 2)]
       
   130 [('headline', 'Article 3'), ('id', 3)]
       
   131 [('headline', 'Article 7'), ('id', 7)]
       
   132 [('headline', 'Article 1'), ('id', 1)]
       
   133 
       
   134 # if you don't specify which fields, all are returned
       
   135 >>> list(Article.objects.filter(id=5).values()) == [{'id': 5, 'headline': 'Article 5', 'pub_date': datetime(2005, 8, 1, 9, 0)}]
       
   136 True
       
   137 
       
   138 # Every DateField and DateTimeField creates get_next_by_FOO() and
       
   139 # get_previous_by_FOO() methods.
       
   140 # In the case of identical date values, these methods will use the ID as a
       
   141 # fallback check. This guarantees that no records are skipped or duplicated.
       
   142 >>> a1.get_next_by_pub_date()
       
   143 <Article: Article 2>
       
   144 >>> a2.get_next_by_pub_date()
       
   145 <Article: Article 3>
       
   146 >>> a2.get_next_by_pub_date(headline__endswith='6')
       
   147 <Article: Article 6>
       
   148 >>> a3.get_next_by_pub_date()
       
   149 <Article: Article 7>
       
   150 >>> a4.get_next_by_pub_date()
       
   151 <Article: Article 6>
       
   152 >>> a5.get_next_by_pub_date()
       
   153 Traceback (most recent call last):
       
   154     ...
       
   155 DoesNotExist: Article matching query does not exist.
       
   156 >>> a6.get_next_by_pub_date()
       
   157 <Article: Article 5>
       
   158 >>> a7.get_next_by_pub_date()
       
   159 <Article: Article 4>
       
   160 
       
   161 >>> a7.get_previous_by_pub_date()
       
   162 <Article: Article 3>
       
   163 >>> a6.get_previous_by_pub_date()
       
   164 <Article: Article 4>
       
   165 >>> a5.get_previous_by_pub_date()
       
   166 <Article: Article 6>
       
   167 >>> a4.get_previous_by_pub_date()
       
   168 <Article: Article 7>
       
   169 >>> a3.get_previous_by_pub_date()
       
   170 <Article: Article 2>
       
   171 >>> a2.get_previous_by_pub_date()
       
   172 <Article: Article 1>
       
   173 
       
   174 # Underscores and percent signs have special meaning in the underlying
       
   175 # SQL code, but Django handles the quoting of them automatically.
       
   176 >>> a8 = Article(headline='Article_ with underscore', pub_date=datetime(2005, 11, 20))
       
   177 >>> a8.save()
       
   178 >>> Article.objects.filter(headline__startswith='Article')
       
   179 [<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>]
       
   180 >>> Article.objects.filter(headline__startswith='Article_')
       
   181 [<Article: Article_ with underscore>]
       
   182 
       
   183 >>> a9 = Article(headline='Article% with percent sign', pub_date=datetime(2005, 11, 21))
       
   184 >>> a9.save()
       
   185 >>> Article.objects.filter(headline__startswith='Article')
       
   186 [<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>]
       
   187 >>> Article.objects.filter(headline__startswith='Article%')
       
   188 [<Article: Article% with percent sign>]
       
   189 
       
   190 # exclude() is the opposite of filter() when doing lookups:
       
   191 >>> Article.objects.filter(headline__contains='Article').exclude(headline__contains='with')
       
   192 [<Article: Article 5>, <Article: Article 6>, <Article: Article 4>, <Article: Article 2>, <Article: Article 3>, <Article: Article 7>, <Article: Article 1>]
       
   193 >>> Article.objects.exclude(headline__startswith="Article_")
       
   194 [<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>]
       
   195 >>> Article.objects.exclude(headline="Article 7")
       
   196 [<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>]
       
   197 
       
   198 # Backslashes also have special meaning in the underlying SQL code, but Django
       
   199 # automatically quotes them appropriately.
       
   200 >>> a10 = Article(headline='Article with \\ backslash', pub_date=datetime(2005, 11, 22))
       
   201 >>> a10.save()
       
   202 >>> Article.objects.filter(headline__contains='\\')
       
   203 [<Article: Article with \ backslash>]
       
   204 
       
   205 # none() returns an EmptyQuerySet that behaves like any other QuerySet object
       
   206 >>> Article.objects.none()
       
   207 []
       
   208 >>> Article.objects.none().filter(headline__startswith='Article')
       
   209 []
       
   210 >>> Article.objects.none().count()
       
   211 0
       
   212 >>> [article for article in Article.objects.none().iterator()]
       
   213 []
       
   214 
       
   215 # using __in with an empty list should return an empty query set
       
   216 >>> Article.objects.filter(id__in=[])
       
   217 []
       
   218 
       
   219 >>> Article.objects.exclude(id__in=[])
       
   220 [<Article: Article with \ backslash>, <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>]
       
   221 
       
   222 # Programming errors are pointed out with nice error messages
       
   223 >>> Article.objects.filter(pub_date_year='2005').count()
       
   224 Traceback (most recent call last):
       
   225     ...
       
   226 TypeError: Cannot resolve keyword 'pub_date_year' into field
       
   227 
       
   228 >>> Article.objects.filter(headline__starts='Article')
       
   229 Traceback (most recent call last):
       
   230     ...
       
   231 TypeError: Cannot resolve keyword 'headline__starts' into field
       
   232 
       
   233 """}