Ticket #7338: method_cache.diff
File method_cache.diff, 7.7 KB (added by , 16 years ago) |
---|
-
django/db/models/sql/query.py
21 21 from django.core.exceptions import FieldError 22 22 from datastructures import EmptyResultSet, Empty, MultiJoin 23 23 from constants import * 24 from django.core.cache import cache 24 25 25 26 try: 26 27 set … … 202 203 fields = self.select_fields + self.related_select_fields 203 204 else: 204 205 fields = self.model._meta.fields 205 for rows in self.execute_sql(MULTI): 206 207 if getattr(self, 'cache_timeout', None): 208 """ 209 Check cache for stored objects from an exactly equal query 210 """ 211 k = str(self) 212 213 try: 214 import hashlib 215 except ImportError: 216 import sha 217 k = sha.new(k).hexdigest() 218 else: 219 k = hashlib.sha1(k).hexdigest() 220 221 if cache.has_key(k) and cache.get(k): 222 sql_result = cache.get(k, []) 223 else: 224 cache.set(k, [i for i in self.execute_sql(MULTI)], self.cache_timeout) 225 sql_result = cache.get(k, []) 226 else: 227 sql_result = self.execute_sql(MULTI) 228 229 for rows in sql_result: 206 230 for row in rows: 207 231 if resolve_columns: 208 232 row = self.resolve_columns(row, fields) -
django/db/models/manager.py
123 123 def reverse(self, *args, **kwargs): 124 124 return self.get_query_set().reverse(*args, **kwargs) 125 125 126 def cache(self, timeout=20): 127 return self.get_query_set().cache(timeout=timeout) 128 126 129 def _insert(self, values, **kwargs): 127 130 return insert_query(self.model, values, **kwargs) 128 131 -
django/db/models/query.py
614 614 """ 615 615 pass 616 616 617 def cache(self, timeout=20): 618 """ 619 Forces the current queryset to check if a exact equal query has been 620 stored in the cache. The expiration time is the seconds in 'timeout' 621 variable 622 """ 623 self.query.cache_timeout = timeout 617 624 625 return self 626 627 618 628 class ValuesQuerySet(QuerySet): 619 629 def __init__(self, *args, **kwargs): 620 630 super(ValuesQuerySet, self).__init__(*args, **kwargs) -
tests/modeltests/queryset_cache/models.py
1 """ 2 40. Storing queryset results in the cache 3 4 Stores objects got with a queryset to the cache, modify one of those, 5 get objects again, check if thei has been stored correctly. 6 7 The porpose of this function is avoid identical queries done to the 8 database in a short time, when possible. 9 """ 10 from datetime import datetime 11 12 from django.db import models 13 14 class Entry(models.Model): 15 title = models.CharField(max_length=100) 16 body = models.TextField(blank=True) 17 pub_date = models.DateTimeField(default=datetime.now) 18 19 def __unicode__(self): 20 return self.title 21 22 class Meta: 23 ordering = ('id',) 24 25 __test__ = {'API_TESTS':""" 26 27 # Tests if cache engine its working 28 >>> from django.core.cache import cache 29 >>> cache.set('name_of_key', 'Tarsila') 30 >>> cache.get('name_of_key') == 'Tarsila' 31 True 32 33 # Create a couple of Entries. 34 >>> e1 = Entry.objects.create(title='My first', body='The one') 35 >>> e2 = Entry.objects.create(title='My second', body='The two') 36 >>> e3 = Entry.objects.create(title='My third', body='The three') 37 >>> e4 = Entry.objects.create(title='My forth', body='The four') 38 39 # Run a non-cached query 40 >>> Entry.objects.all() 41 [<Entry: My first>, <Entry: My second>, <Entry: My third>, <Entry: My forth>] 42 43 # Modify one 44 >>> e1.title = 'The first'; e1.save() 45 46 # Run a non-cached query again 47 >>> Entry.objects.all() 48 [<Entry: The first>, <Entry: My second>, <Entry: My third>, <Entry: My forth>] 49 50 # Run a cached query 51 >>> Entry.objects.cache(120) 52 [<Entry: The first>, <Entry: My second>, <Entry: My third>, <Entry: My forth>] 53 54 # Modify one 55 >>> e1.title = 'My first'; e1.save() 56 57 # Run a cached query again (not changed) 58 >>> Entry.objects.cache(120) 59 [<Entry: The first>, <Entry: My second>, <Entry: My third>, <Entry: My forth>] 60 61 # Run a non-cached query (changed) 62 >>> Entry.objects.all() 63 [<Entry: My first>, <Entry: My second>, <Entry: My third>, <Entry: My forth>] 64 """} -
docs/db-api.txt
1071 1071 ``extra()`` is new. Previously, you could attempt to pass parameters for 1072 1072 ``select`` in the ``params`` argument, but it worked very unreliably. 1073 1073 1074 ``cache(timeout=20)`` 1075 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 1076 1077 **New in Django development version** 1078 1079 Use the ``cache()`` method to store the queryset's elements to the cache, for the expiration time 1080 defined by the optional argument ``timeout`` (in seconds). 1081 1082 Examples:: 1083 1084 >>> Entry.objects.cache(300) 1085 [<Entry: Beyond the database>] 1086 1087 The example above evaluates to this SQL: 1088 1089 SELECT 1090 "diario_entry"."id", "diario_entry"."title", "diario_entry"."slug", 1091 "diario_entry"."body_source", "diario_entry"."body", "diario_entry"."markup", 1092 "diario_entry"."is_draft", "diario_entry"."pub_date", "diario_entry"."tags", 1093 "diario_entry"."content_type_id", "diario_entry"."object_id" 1094 FROM "diario_entry" 1095 ORDER BY "diario_entry"."pub_date" DESC 1096 1097 When using the method ``cache()``, before request the results for this query from the database the 1098 ORM will generate a hash code for this SQL and will check in the cache for an item with the same 1099 hash code, what means that if an identical query has been done before, it will be stored in memory 1100 and will return with on request to database server. 1101 1102 The expiration time (``timeout`` argument) defines how many seconds the cache engine will handle the 1103 objects. 1104 1105 You can also define that all queries from a model class are stored in the cache, like the example 1106 below:: 1107 1108 class EntryManager(models.Manager): 1109 def get_query_set(self): 1110 q = super(EntryManager, self).get_query_set() 1111 1112 return q.cache(120) 1113 1114 This will make all queryset from ``Entry`` model class be made with the ``cache()`` method. 1115 1116 **Important observations**:: 1117 1118 * You have to keep in your mind that cached objects are not the best way for all cases, because 1119 sometimes you need to get results exactly as they are in database. E.g: in the admin site. Be 1120 careful when using this method, you can have problems getting old values thinking that the ORM 1121 is crazy; 1122 1123 * The usage of this method makes sense only with memory based cache engines (``memcached`` and 1124 ``locmem``); 1125 1126 * The main function of this method is increase the scalability of your querysets. The logic 1127 sense of this method is: more concurrent users you have, less queries to the database. 1128 1074 1129 QuerySet methods that do not return QuerySets 1075 1130 --------------------------------------------- 1076 1131