Django Caching a User Profile

I am trying to cache access to a Django profile object. I am using django-redis-cache to cache data in this project. I use a snippet to automatically create a profile if it does not exist. Here is a simplified version of what I am doing (without caching):

User.profile = property(lambda u: UserProfile.objects.get_or_create(user=u)[0]) 

Whenever profile information is required, the user.profile property is accessed. This works as expected, however, when I try to cache the profile property, for example, in Appendix 1, I still see SQL queries (in django-debug-toolbar) that select the profile and do not use the cache.

In particular, the cache_object_list () function from Appendix 2 is a bit of code that checks if a cached value is available. If so, it calls the cache key. If not, it executes the query passed to it (via the query argument) and caches the results.

cache_object_list () prints "Hit" or "Miss", indicating defeat or missing cache. After updating twice, everything is reported as a hit (as expected). However, the django-debug toolbar still does not show a reduction in the number of requests and shows requests that select a profile.

Does anyone have any tips on how to ensure that user.profile pulls out the cached version of the profile when it is available? Thank you for reading.

Figure 1: myproject / myapp / models.py

 def get_or_create_profile(u): return cache_utils.cache_single_object( "user_get_or_create_profile", u.id, UserProfile.objects.get_or_create(user=u)[0]) User.profile = property(lambda u: cache_utils.cache_single_object( "user_get_or_create_profile", u.id, get_or_create_profile(u))) 

Figure 2: myproject / cache_utils.py

 def cache_single_object(key_prefix, id, query, timeout=500): key = '%s_%s' % (key_prefix, id) object_list = cache.get(key, None) if object_list is None: print "Miss %s" % (key) object_list = query cache.set(key, object_list, timeout) else: print "Hit %s" % (key) return object_list 

Figure 3: myproject / templates / mytemplate.py

 <div>Example of what in the template </div> {{ myobject.owner.profile.bio }} 
+4
source share
1 answer

I think the problem is with how you defined your method ....

 User.profile = property(lambda u: cache_utils.cache_single_object( "user_get_or_create_profile", u.id, get_or_create_profile(u))) 

when you access the profile property, you always call the get_or_create_profile (u) method, which calls:

 return cache_utils.cache_single_object( "user_get_or_create_profile", u.id, UserProfile.objects.get_or_create(user=u)[0]) 

with UserProfile.objects.get_or_create (user = u) there is something that creates your request every time, even if you already have data in the cache. I think you should try using the util method, where you will not evaluate the request every time you call it. Maybe something like this: fooobar.com/questions/1429826 / ...

+2
source

All Articles