django-user-sessions makes Django sessions queryable by user
Extend Django sessions with a foreign key back to the user, allowing enumerating all user's sessions.
At a glance
- What is it?
- django-user-sessions is a drop-in replacement for django.contrib.sessions that adds a foreign key back to the user, so you can list a user's active sessions, log them out everywhere and show IP address and user agent. It suits any Django app that needs a devices or sessions screen, and it depends on GeoIP being configured for location detection.
- Who is it for?
- Adopt django-user-sessions when your Django application needs a sessions or devices screen, needs the ability to sign a user out of all their devices, or wants to show where a session came from. Do not adopt it if you only need Django's built-in sessions, since the built-in ones are simpler and you would be taking on a table migration and a dependency for no benefit.
- Can I use it commercially?
- Yes. MIT is a permissive licence: you can use, modify and sell software built on it, as long as you keep its copyright and licence notices.
- Is it still maintained?
- Yes. The repository last received commits 4 days ago.
- What is it written in?
- Mainly Python, according to GitHub's language statistics.
Answers come from the project's GitHub data, last synced on October 23, 2026, and from our analysis. They are not legal advice.
Editorial analysis
The problem is that session data is base64 in a blob
The explanation of why this package exists is short and precise. Django includes excellent built-in sessions, however all the data is hidden away into base64 encoded data, which makes it very difficult to run a query on all active sessions for a particular user. django-user-sessions fixes this and makes session objects a first class citizen like other ORM objects, and it is a drop-in replacement for django.contrib.sessions. That last phrase is the operational claim that matters, because the built-in session store is a single model with a key, a data blob and an expiry date, and replacing it means pointing the session engine setting at a different backend and migrating. Once it is in place, the two operations the package exists for are ordinary ORM calls. To get the list of a user's sessions you filter the related manager on the expiry date:
user.session_set.filter(expire_date__gt=now())and to log the user out everywhere you delete the whole set:
user.session_set.all().delete()The second one is the capability that built-in sessions simply do not offer, and it is the reason a lot of applications end up writing a custom session store.
IP address, user agent and location come along with it
The session record keeps the user's IP address and user agent, and the documentation says this allows showing a list of active sessions to the user in the admin, with a screenshot of the admin list, and also in a custom layout. The storage of the IP address is what makes location detection possible, and that has a dependency you need to satisfy. You need to setup GeoIP for the location detection to work, with a pointer to the Django documentation on installing GeoIP. That is a system level dependency rather than a Python one, and it is the step most likely to be missed, because the session list still works without it, the location column is what silently stays empty. The package is a Jazzband project, and the project page notes that it is translated into English, Dutch and other languages, with contributions through Transifex. The repository also bundles example templates and views, and the documentation points you at them to see how the application can be integrated into your project, which is a genuinely useful starting point rather than a documentation exercise.
Compatibility is narrow and worth checking before you install
The compatibility statement in the README is that it is compatible with Django 3.2 and 4.2 on Python 3.8 to 3.11. The packaging metadata is a little wider than that prose. It requires Python 3.8 or newer, depends on Django 3.2 or newer, and the classifiers list Framework Django 3.2 and 4.2 alongside Python versions 3.8 through 3.12. The package itself has exactly one runtime dependency, Django, and everything else in the optional extras is tooling, with the example app, testing, Transifex and documentation groups covering django-debug-toolbar, coverage, tox, transifex-client, Sphinx, bumpversion and twine. The release history is where the other important fact sits. The most recent releases are 1.7.1 from 2020-01-24 and 1.7.0 from 2020-01-19, with 1.6.0 from 2017-12-19 before that. The repository is not archived and the last push was on 2026-10-19, so the code is still being touched, but there has been no tagged release in more than six years. The changelog is published on the documentation site under release notes, and that is the first place to look before upgrading a project that has been running for a long time.
Swapping the session engine and running the migration
Because this replaces a built-in component, the install has a data step that most package installs do not. The release procedure documented in the README shows how migrations are made in this project, and the same command applies to your own project, where you generate the migrations for the user_sessions app after pointing your session engine at it. The release checklist is also a good description of the moving parts. Update release notes, and if new translation strings were added, push the new source language to Transifex with make tx-push, giving translators time to translate the new strings. Then add migrations, with the example command being python example/manage.py makemigrations user_sessions followed by a git commit of the migrations directory. Then update the translations with make tx-pull, and finally package and upload with bumpversion for major, minor or patch, a git push with tags, a wheel build with python -m build --wheel, and twine upload of the built distribution. The migration step is the one that matters for an adopter, since it creates the table that replaces the built-in session table.
The test suite wants a database container and a full coverage bar
The development setup reveals a project that takes its own testing seriously. The README says the project aims for full code-coverage, meaning your code should be well-tested, and it also asks you to test branches for hardened code. The Makefile shows the cost of that. The test target depends on a fixture generation step that builds a Docker image from tests/Dockerfile and runs it to produce the GeoIP test database, so running the tests needs Docker even though the package itself does not. The suite is then run with the Django test runner, and you can narrow it with a target argument, for example a specific middleware test class. There is also a coverage target that runs the example project's own manage.py with coverage, then generates the HTML report and prints the summary. The Makefile also has targets for running the bundled example application and for checking the Django configuration, both pointing at example.settings with the example directory on the Python path. The tox configuration is there for Python version compatibility, and the full suite can be run with tox. The tests/ directory also holds a conftest with the settings and fixtures for the test suite.
Editorial conclusion
Adopt django-user-sessions when your Django application needs a sessions or devices screen, needs the ability to sign a user out of all their devices, or wants to show where a session came from. Do not adopt it if you only need Django's built-in sessions, since the built-in ones are simpler and you would be taking on a table migration and a dependency for no benefit. Verify first that your Django version is covered by the stated compatibility of 3.2 and 4.2, that GeoIP is set up on the host if you want location detection to work, and that you have read the release notes, since the last tagged release is 1.7.1 from January 2020.
Frequently asked questions
What does django-user-sessions add over django.contrib.sessions?
It adds a foreign key back to the user, so sessions become first class ORM objects. That makes it possible to list a user's active sessions with user.session_set.filter(expire_date__gt=now()) and to log the user out everywhere with user.session_set.all().delete(), which the base64 encoded data of the built-in store does not allow.
What do I need for the session list to show locations?
You need to set up GeoIP for the location detection to work, following the Django documentation on installing GeoIP. The session list itself works without it, but the location column depends on that system level setup.
How do I run the tests for django-user-sessions?
Run make test, which first builds a Docker image to generate the GeoIP test database fixtures and then runs the Django test suite. You can narrow it to a single test class with make test TARGET=tests.tests.MiddlewareTest, and the full suite across Python versions with tox.
Which Django and Python versions does django-user-sessions support?
The README states compatibility with Django 3.2 and 4.2 on Python 3.8 to 3.11, while the packaging metadata requires Python 3.8 or newer and Django 3.2 or newer, with classifiers covering Python 3.8 through 3.12. The package depends only on Django at runtime, and is MIT licensed.
Official sources
Add this badge to your README
If you maintain this project, the badge below links readers to this analysis and shows its maintenance status from the daily GitHub snapshot. Paste the markdown into your README; add ?metric=license or ?metric=stars to the image URL for a different field.
[](https://hysenlabs.com/projects/jazzband-django-user-sessions)Was this useful?