Django Impersonate
Django Impersonate is a Django application that allows superusers (or users with specific permissions) to temporarily assume the identity of another user. This is highly useful for debugging, support, or testing user experiences. The current version is 1.9.5, and it is actively maintained with regular releases aligning with Django and Python version compatibility updates.
Common errors
-
NoReverseMatch at /impersonate/...
cause This usually indicates that the `impersonate.urls` are not correctly included in your project's `urls.py`, or there's a mismatch in how URL patterns are defined (e.g., using `url()` instead of `path()` for newer Django versions).fixAdd `path('impersonate/', include('impersonate.urls'))` to your project's `urlpatterns` in `urls.py`. Also, ensure you are using `path()` if your Django version is 2.0 or higher. -
TypeError: __init__() missing 1 required positional argument: 'get_response' OR ImpersonateMiddleware not working as expected.
cause This error or silent failure of the middleware typically means `ImpersonateMiddleware` is not properly placed in your `settings.MIDDLEWARE` list, or not listed at all.fixEnsure `impersonate.middleware.ImpersonateMiddleware` is present in your `settings.MIDDLEWARE` list, and crucially, that it comes *after* `django.contrib.sessions.middleware.SessionMiddleware` and `django.contrib.auth.middleware.AuthenticationMiddleware`. -
You do not have permission to impersonate users.
cause The current user attempting to impersonate does not meet the required permissions. By default, only `is_superuser` users can impersonate.fixLog in as a superuser. If you want to allow non-superusers, set `IMPERSONATE_REQUIRE_SUPERUSER = False` in your `settings.py` and potentially define `IMPERSONATE_CUSTOM_USER_QUERY` to specify who can impersonate. You may also need to clear browser cookies after changing impersonation settings.
Warnings
- breaking Prior to version 1.7.0, django-impersonate used `django.conf.urls.url` for its URL patterns. Projects upgrading from older Django versions (pre-2.0) that also used `url()` in their project's `urls.py` would have been compatible. From 1.7.0 onwards, it uses `django.urls.path`. If your project's `urls.py` still uses `url()` and you upgrade django-impersonate to 1.7.0+, you might face `NoReverseMatch` errors or URL resolution issues if not updated to `path()`.
- breaking In version 1.8.0, the `login_url` used for redirection after an unsuccessful impersonation attempt changed from a hardcoded `/accounts/login/` to dynamically using `django.conf.settings.LOGIN_URL`. If your project previously relied on the hardcoded path and did not have `LOGIN_URL` defined, this might cause unexpected redirection behavior.
- gotcha The `ImpersonateMiddleware` must be placed correctly in your `MIDDLEWARE` setting. It relies on `SessionMiddleware` and `AuthenticationMiddleware` to function correctly, meaning it must appear *after* both of them in the `MIDDLEWARE` list.
- gotcha Impersonation links or buttons might not appear, or the impersonation functionality might not work as expected, due to incorrect user permissions or configuration. By default, only superusers can impersonate. You can change this behavior with `IMPERSONATE_REQUIRE_SUPERUSER` or `IMPERSONATE_CUSTOM_USER_QUERY`.
Install
-
pip install django-impersonate
Imports
- ImpersonateMiddleware
from impersonate.middleware import ImpersonateMiddleware
- impersonate_urls
from django.urls import path, include urlpatterns = [ path('impersonate/', include('impersonate.urls')), # ... ] - impersonate_context_processor
from impersonate.context_processors import impersonate
Quickstart
# settings.py
INSTALLED_APPS = [
# ...
'impersonate',
]
MIDDLEWARE = [
# ...
'django.contrib.sessions.middleware.SessionMiddleware',
'django.contrib.auth.middleware.AuthenticationMiddleware',
'impersonate.middleware.ImpersonateMiddleware', # Must be AFTER Session and Auth middleware
# ...
]
# urls.py
from django.urls import path, include
from django.contrib import admin
urlpatterns = [
path('admin/', admin.site.urls),
path('impersonate/', include('impersonate.urls')),
# ... your other urls
]
# In a template (e.g., base.html) to show an impersonation link:
# {% load impersonate_tags %}
# {% if user.is_authenticated and user.is_superuser %}
# {% if impersonate %} # 'impersonate' variable comes from context processor
# <a href="{% url 'impersonate-leave' %}">Leave Impersonation</a>
# {% else %}
# <a href="{% url 'impersonate-start' user_id=1 %}">Impersonate User (ID 1)</a> # Replace 1 with actual user ID
# <a href="{% url 'impersonate-start' username='testuser' %}">Impersonate User (username testuser)</a>
# {% endif %}
# {% endif %}