Ticket #8484: models.py

File models.py, 3.9 KB (added by ckelly, 16 years ago)

extra_regress test models.py with additional extra() caching test

Line 
1import copy
2
3from django.contrib.auth.models import User
4from django.db import models
5from django.db.models.query import Q
6from django.utils.datastructures import SortedDict
7from django.core.cache import cache
8
9class RevisionableModel(models.Model):
10 base = models.ForeignKey('self', null=True)
11 title = models.CharField(blank=True, max_length=255)
12
13 def __unicode__(self):
14 return u"%s (%s, %s)" % (self.title, self.id, self.base.id)
15
16 def save(self):
17 super(RevisionableModel, self).save()
18 if not self.base:
19 self.base = self
20 super(RevisionableModel, self).save()
21
22 def new_revision(self):
23 new_revision = copy.copy(self)
24 new_revision.pk = None
25 return new_revision
26
27class Order(models.Model):
28 created_by = models.ForeignKey(User)
29 text = models.TextField()
30
31__test__ = {"API_TESTS": """
32# Regression tests for #7314 and #7372
33
34>>> rm = RevisionableModel.objects.create(title='First Revision')
35>>> rm.pk, rm.base.pk
36(1, 1)
37
38>>> rm2 = rm.new_revision()
39>>> rm2.title = "Second Revision"
40>>> rm2.save()
41>>> print u"%s of %s" % (rm2.title, rm2.base.title)
42Second Revision of First Revision
43
44>>> rm2.pk, rm2.base.pk
45(2, 1)
46
47Queryset to match most recent revision:
48>>> qs = RevisionableModel.objects.extra(where=["%(table)s.id IN (SELECT MAX(rev.id) FROM %(table)s rev GROUP BY rev.base_id)" % {'table': RevisionableModel._meta.db_table,}],)
49>>> qs
50[<RevisionableModel: Second Revision (2, 1)>]
51
52Queryset to search for string in title:
53>>> qs2 = RevisionableModel.objects.filter(title__contains="Revision")
54>>> qs2
55[<RevisionableModel: First Revision (1, 1)>, <RevisionableModel: Second Revision (2, 1)>]
56
57Following queryset should return the most recent revision:
58>>> qs & qs2
59[<RevisionableModel: Second Revision (2, 1)>]
60
61>>> u = User.objects.create_user(username="fred", password="secret", email="fred@example.com")
62
63# General regression tests: extra select parameters should stay tied to their
64# corresponding select portions. Applies when portions are updated or otherwise
65# moved around.
66>>> qs = User.objects.extra(select=SortedDict((("alpha", "%s"), ("beta", "2"), ("gamma", "%s"))), select_params=(1, 3))
67>>> qs = qs.extra(select={"beta": 4})
68>>> qs = qs.extra(select={"alpha": "%s"}, select_params=[5])
69>>> result = {'alpha': 5, 'beta': 4, 'gamma': 3}
70>>> list(qs.filter(id=u.id).values('alpha', 'beta', 'gamma')) == [result]
71True
72
73# Regression test for #7957: Combining extra() calls should leave the
74# corresponding parameters associated with the right extra() bit. I.e. internal
75# dictionary must remain sorted.
76>>> User.objects.extra(select={"alpha": "%s"}, select_params=(1,)).extra(select={"beta": "%s"}, select_params=(2,))[0].alpha
771
78>>> User.objects.extra(select={"beta": "%s"}, select_params=(1,)).extra(select={"alpha": "%s"}, select_params=(2,))[0].alpha
792
80
81# Regression test for #7961: When not using a portion of an extra(...) in a
82# query, remove any corresponding parameters from the query as well.
83>>> list(User.objects.extra(select={"alpha": "%s"}, select_params=(-6,)).filter(id=u.id).values_list('id', flat=True)) == [u.id]
84True
85
86# Regression test for #8063: limiting a query shouldn't discard any extra()
87# bits.
88>>> qs = User.objects.all().extra(where=['id=%s'], params=[u.id])
89>>> qs
90[<User: fred>]
91>>> qs[:1]
92[<User: fred>]
93
94# Regression test for #8039: Ordering sometimes removed relevant tables from
95# extra(). This test is the critical case: ordering uses a table, but then
96# removes the reference because of an optimisation. The table should still be
97# present because of the extra() call.
98>>> Order.objects.extra(where=["username=%s"], params=["fred"], tables=["auth_user"]).order_by('created_by')
99[]
100
101##################################
102# Pickling a queryset with extra #
103##################################
104>>> qs = RevisionableModel.objects.extra(select={"rm_count": "SELECT COUNT(*) from extra_regress_revisionablemodel"})
105>>> cache.set("extra_test", qs)
106>>> new_qs = cache.get("extra_test")
107
108"""}
Back to Top