Friday, 23 May 2014

Django get current user globally in the project

Sometimes, you will need to get the current authenticated user in models, or other parts of your app.

To achieve this, you must create this middleware and add it to MIDDLEWARE_CLASSES in project settings:
try:
from threading import local, current_thread
except ImportError:
from django.utils._threading_local import local

_thread_locals = local()


class GlobalUserMiddleware(object):
"""
Sets the current authenticated user in threading locals

Usage example:
from app_name.middleware import get_current_user
user = get_current_user()
"""
def process_request(self, request):
setattr(
_thread_locals,
'user_{0}'.format(current_thread().name),
request.user)

def process_response(self, request, response):

key = 'user_{0}'.format(current_thread().name)

if not hasattr(_thread_locals, key):
return response

delattr(_thread_locals, key)

return response


def get_current_user():
return getattr(
_thread_locals,
'user_{0}'.format(current_thread().name),
None)

Usage example:
from myapp.middleware import get_current_user

user = get_current_user()

Wednesday, 21 May 2014

Invalidate template fragment cache in Django 1.5

Django 1.5 does not have a utility method to delete template fragment cache, with arguments.

In order to achieve this, you must create a custom method:
from django.core.cache import cache
from django.utils.hashcompat import md5_constructor
from django.utils.http import urlquote


def invalidate_template_fragment(fragment_name, *variables):
args = md5_constructor(u':'.join([urlquote(var) for var in variables]))
cache_key = 'template.cache.{0}.{1}'.format(fragment_name, args.hexdigest())
cache.delete(cache_key)

Example usage:
{% cache 259200 key_name model_instance.pk %}
... cached content here ...
{% endcache %}

// note that "model_instance.pk" is optional argument. You can use as many as you need

... and delete the cache:
invalidate_template_fragment('key_name', model_instance.pk)

 

In django 1.6+ you can do this more easy:
from django.core.cache import cache
from django.core.cache.utils import make_template_fragment_key

key = make_template_fragment_key('key_name', [model_instance.pk])
cache.delete(key)