Django-CRUM

0.7.9 · maintenance · verified Wed Apr 15

Django-CRUM (Current Request User Middleware) captures the current request and user in thread local storage. It enables Django applications to check permissions, capture audit trails, or access the current request and user without requiring the request object to be passed directly. It also provides a context manager for temporarily impersonating another user. The current version is 0.7.9, released on November 10, 2020, and it is tested against various Django versions from 1.11 up to 4.0, and Python versions from 3.4 to 3.9.

Warnings

Install

Imports

Quickstart

To use django-crum, first install the package. Then, add `CurrentRequestUserMiddleware` to your Django project's `MIDDLEWARE` setting. You can then import and use `get_current_request()`, `get_current_user()`, or the `impersonate()` context manager within your application code, for example, in model `save` methods or custom logic, to access the current request or user.

# settings.py
MIDDLEWARE = [
    # ... other middleware ...
    'crum.CurrentRequestUserMiddleware',
    # ... other middleware that might need request/user ...
]

# myapp/models.py (example)
from django.db import models
from django.conf import settings
from crum import get_current_user, get_current_request, impersonate

class AuditModel(models.Model):
    created_at = models.DateTimeField(auto_now_add=True)
    created_by = models.ForeignKey(
        settings.AUTH_USER_MODEL, 
        on_delete=models.SET_NULL, 
        null=True, 
        blank=True,
        related_name='created_%(class)ss'
    )
    last_modified_at = models.DateTimeField(auto_now=True)
    last_modified_by = models.ForeignKey(
        settings.AUTH_USER_MODEL, 
        on_delete=models.SET_NULL, 
        null=True, 
        blank=True,
        related_name='modified_%(class)ss'
    )
    request_ip = models.GenericIPAddressField(null=True, blank=True)

    def save(self, *args, **kwargs):
        user = get_current_user()
        request = get_current_request()
        
        if not self.pk: # Object is being created
            if user and user.is_authenticated:
                self.created_by = user
        
        # Always update last_modified_by
        if user and user.is_authenticated:
            self.last_modified_by = user
        
        # Capture IP address from request if available
        if request:
            self.request_ip = request.META.get('REMOTE_ADDR')

        super().save(*args, **kwargs)

    class Meta:
        abstract = True

class MyItem(AuditModel):
    name = models.CharField(max_length=255)

    def __str__(self):
        return self.name

# Example of impersonation (e.g., in a background task or management command)
# from django.contrib.auth import get_user_model
# User = get_user_model()
# special_user = User.objects.get(username='system_user') # An existing user
# with impersonate(special_user):
#    new_item = MyItem.objects.create(name='Automated Report')
#    print(f"Item '{new_item.name}' created by: {new_item.created_by.username}")

view raw JSON →