Create a gist now

Instantly share code, notes, and snippets.

What would you like to do?
Add user created/modified to every model
"""Add user created_by and modified_by foreign key refs to any model automatically.
Almost entirely taken from"""
from django.db.models import signals
from django.utils.functional import curry
class WhodidMiddleware(object):
def process_request(self, request):
if not request.method in ('GET', 'HEAD', 'OPTIONS', 'TRACE'):
if hasattr(request, 'user') and request.user.is_authenticated():
user = request.user
user = None
mark_whodid = curry(self.mark_whodid, user)
signals.pre_save.connect(mark_whodid, dispatch_uid = (self.__class__, request,), weak = False)
def process_response(self, request, response):
signals.pre_save.disconnect(dispatch_uid = (self.__class__, request,))
return response
def mark_whodid(self, user, sender, instance, **kwargs):
if not getattr(instance, 'created_by_id', None):
instance.created_by = user
if hasattr(instance,'modified_by_id'):
instance.modified_by = user

Brilliant. Thanks!

anujism commented Jul 13, 2016

How to use this?

Fantastic. It really helps me a lot.

lukik commented Oct 22, 2016

October 2016. With Django==1.10.2 and djangorestframework==3.4.7 it still works with no modification whatsoever. Thanks.

Can you provide an example to use within a model?

stevelacey commented Feb 14, 2017

I keep coming back to this gist on projects, it's a good DRY solution to the problem.

If anyone needs it to also work with Django REST Framework (which uses its own auth system), you can manually fire the DRF backends you use there by swapping the user = lines above out for something like this which tries the same but falls back to DRF if unauthed:

from rest_framework import authentication

    user = request.user
    if not user.is_authenticated():
        auth = authentication.BasicAuthentication().authenticate(request)
        if auth:
            user = auth[0]
            user = None
except (authentication.exceptions.AuthenticationFailed, KeyError):
    user = None

Modify to suit your needs aka your backends which are hopefully not basic auth – if anyone can be bothered I imagine this can be improved to pull the backends you use out of without too much difficulty.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment