55from django .core .cache .backends .db import Options
66from django .db import connections , router
77from django .utils .functional import cached_property
8+ from pymongo import IndexModel
89from pymongo .errors import DuplicateKeyError
910
1011
@@ -41,20 +42,29 @@ class CacheEntry:
4142 self .cache_model_class = CacheEntry
4243
4344 def create_indexes (self ):
44- self .collection .create_index ("expires_at" , expireAfterSeconds = 0 )
45- self .collection .create_index ("key" , unique = True )
45+ expires_index = IndexModel ("expires_at" , expireAfterSeconds = 0 )
46+ key_index = IndexModel ("key" , unique = True )
47+ self .collection_to_write .create_indexes ([expires_index , key_index ])
4648
4749 @cached_property
4850 def serializer (self ):
4951 return MongoSerializer (self .pickle_protocol )
5052
5153 @property
52- def _db (self ):
54+ def _db_to_read (self ):
5355 return connections [router .db_for_read (self .cache_model_class )]
5456
5557 @property
56- def collection (self ):
57- return self ._db .get_collection (self ._collection_name )
58+ def collection_to_read (self ):
59+ return self ._db_to_read .get_collection (self ._collection_name )
60+
61+ @property
62+ def _db_to_write (self ):
63+ return connections [router .db_for_write (self .cache_model_class )]
64+
65+ @property
66+ def collection_to_write (self ):
67+ return self ._db_to_read .get_collection (self ._collection_name )
5868
5969 def get (self , key , default = None , version = None ):
6070 result = self .get_many ([key ], version )
@@ -71,18 +81,18 @@ def get_many(self, keys, version=None):
7181 if not keys :
7282 return {}
7383 keys_map = {self .make_and_validate_key (key , version = version ): key for key in keys }
74- with self .collection .find (
84+ with self .collection_to_read .find (
7585 {"key" : {"$in" : tuple (keys_map )}, ** self ._filter_expired (expired = False )}
7686 ) as cursor :
7787 return {keys_map [row ["key" ]]: self .serializer .loads (row ["value" ]) for row in cursor }
7888
7989 def set (self , key , value , timeout = DEFAULT_TIMEOUT , version = None ):
8090 key = self .make_and_validate_key (key , version = version )
8191 serialized_data = self .serializer .dumps (value )
82- num = self .collection .count_documents ({})
92+ num = self .collection_to_write .count_documents ({})
8393 if num >= self ._max_entries :
8494 self ._cull (num )
85- return self .collection .update_one (
95+ return self .collection_to_write .update_one (
8696 {"key" : key },
8797 {
8898 "$set" : {
@@ -97,11 +107,11 @@ def set(self, key, value, timeout=DEFAULT_TIMEOUT, version=None):
97107 def add (self , key , value , timeout = DEFAULT_TIMEOUT , version = None ):
98108 key = self .make_and_validate_key (key , version = version )
99109 serialized_data = self .serializer .dumps (value )
100- num = self .collection .count_documents ({})
110+ num = self .collection_to_write .count_documents ({})
101111 if num >= self ._max_entries :
102112 self ._cull (num )
103113 try :
104- self .collection .update_one (
114+ self .collection_to_write .update_one (
105115 {"key" : key , ** self ._filter_expired (expired = True )},
106116 {
107117 "$set" : {
@@ -124,7 +134,7 @@ def _cull(self, num):
124134 try :
125135 # Delete the first expiration date.
126136 deleted_from = next (
127- self .collection .aggregate (
137+ self .collection_to_write .aggregate (
128138 [
129139 {"$sort" : {"expires_at" : - 1 , "key" : 1 }},
130140 {"$skip" : keep_num },
@@ -136,7 +146,7 @@ def _cull(self, num):
136146 except StopIteration :
137147 pass
138148 else :
139- self .collection .delete_many (
149+ self .collection_to_write .delete_many (
140150 {
141151 "$or" : [
142152 {"expires_at" : {"$lt" : deleted_from ["expires_at" ]}},
@@ -152,7 +162,7 @@ def _cull(self, num):
152162
153163 def touch (self , key , timeout = DEFAULT_TIMEOUT , version = None ):
154164 key = self .make_and_validate_key (key , version = version )
155- res = self .collection .update_one (
165+ res = self .collection_to_write .update_one (
156166 {"key" : key }, {"$set" : {"expires_at" : self ._get_expiration_time (timeout )}}
157167 )
158168 return res .matched_count > 0
@@ -173,13 +183,16 @@ def _delete_many(self, keys, version=None):
173183 if not keys :
174184 return False
175185 keys = tuple (self .make_and_validate_key (key , version = version ) for key in keys )
176- return bool (self .collection .delete_many ({"key" : {"$in" : keys }}).deleted_count )
186+ return bool (self .collection_to_write .delete_many ({"key" : {"$in" : keys }}).deleted_count )
177187
178188 def has_key (self , key , version = None ):
179189 key = self .make_and_validate_key (key , version = version )
180190 return (
181- self .collection .count_documents ({"key" : key , ** self ._filter_expired (expired = False )}) > 0
191+ self .collection_to_read .count_documents (
192+ {"key" : key , ** self ._filter_expired (expired = False )}
193+ )
194+ > 0
182195 )
183196
184197 def clear (self ):
185- self .collection .delete_many ({})
198+ self .collection_to_write .delete_many ({})
0 commit comments