Showing Models of Internal and 3rd Party Apps in Django Admin Page

Abenezer Belachew

Abenezer Belachew · June 05, 2024

5 min read

  • I came across a situation where I needed to remove a user's session data to force them to log in again. Initially, I did this by deleting the user's session data from the database (stored in a table called django_session by default), but that proved to be too much of a hassle for something that can technically be done with a single click in the admin page.

  • Now the session model is not in the admin page by default, but you can display it there by registering it in the admin.py file of your project. Although I'm using the sessions app as an example here, this can be applied to any of Django's internal apps or any 3rd party apps you have installed.

  • If you take a look at the INSTALLED_APPS in your settings.py file, you'll see a list of apps that Django uses internally.

settings.py

INSTALLED_APPS = [
    'django.contrib.admin',
    'django.contrib.auth',
    'django.contrib.contenttypes',
    'django.contrib.sessions',
    'django.contrib.messages',
    'django.contrib.staticfiles',
    ...
]
  • They show the path to the app's location in your project.

    • If you're using a virtual environment, when you navigate to the site-packages folder in your virtual environment, you'll see a django folder. Inside that folder, you'll see a contrib folder, and inside that folder, you'll see the apps listed in the INSTALLED_APPS list above (like admin, auth, contenttypes, sessions, etc).
  • Whatever you have in your INSTALLED_APPS list is basically the path to the app.

  • If you were to go to the folders of these apps, you'll see that they have files like models.py, api.py, views.py, serializers.py etc. For those apps that have models, you can display them in "your" admin page by registering them in one of the existing admin.py files in your local apps or a new one you create.

  • Navigate to the models.py file of the app you want to display in the admin page.

  • The sessions app, for example, has a models.py file that looks like this:

django/contrib/sessions/models.py
class Session(AbstractBaseSession):
    """
    Django provides full support for anonymous sessions. The session
    framework lets you store and retrieve arbitrary data on a
    per-site-visitor basis. It stores data on the server side and
    abstracts the sending and receiving of cookies. Cookies contain a
    session ID -- not the data itself.

    The Django sessions framework is entirely cookie-based. It does
    not fall back to putting session IDs in URLs. This is an intentional
    design decision. Not only does that behavior make URLs ugly, it makes
    your site vulnerable to session-ID theft via the "Referer" header.

    For complete documentation on using Sessions in your code, consult
    the sessions documentation that is shipped with Django (also available
    on the Django web site).
    """

    objects = SessionManager()

    @classmethod
    def get_session_store_class(cls):
        from django.contrib.sessions.backends.db import SessionStore

        return SessionStore

    class Meta(AbstractBaseSession.Meta):
        db_table = "django_session"

and if you go to the class it's inheriting from, AbstractBaseSession, you'll see this:

django/contrib/sessions/base_session.py
class AbstractBaseSession(models.Model):
    session_key = models.CharField(_("session key"), max_length=40, primary_key=True)
    session_data = models.TextField(_("session data"))
    expire_date = models.DateTimeField(_("expire date"), db_index=True)

    objects = BaseSessionManager()

    class Meta:
        abstract = True
        verbose_name = _("session")
        verbose_name_plural = _("sessions")

    def __str__(self):
        return self.session_key

    @classmethod
    def get_session_store_class(cls):
        raise NotImplementedError

    def get_decoded(self):
        session_store_class = self.get_session_store_class()
        return session_store_class().decode(self.session_data)
  • The Session model has a session_key, session_data, and expire_date fields, as well as a couple of methods.

  • Using that information, we can display the Session model in our own admin page by registering it in the admin.py file of our project. We can even add customizations to only show the fields we want, make some fields read-only, add a search field, add custom methods to show related data (like the user who owns the session), etc.

admin.py
from django.contrib import admin
from django.contrib.sessions.models import Session
from django.contrib.auth.models import User  # or whatever your user model is

@admin.register(Session)
class SessionAdmin(admin.ModelAdmin):
    list_display = ('session_key', 'expire_date', 'user')
    readonly_fields = ['session_key', 'session_data', 'expire_date']
    search_fields = ['session_key']

    def user(self, obj):
        session_data = obj.get_decoded()
        user_id = session_data.get('_auth_user_id')
        try:
            user = User.objects.get(pk=user_id)
            return user.username
        except User.DoesNotExist:
            return 'Anonymous'

    def session_data(self, obj):
        return obj.get_decoded()
Session model in Django admin page

Session model in Django admin page

Once you open it, you can see the session data

Once opened, you can see the list of sessions. You can log out a user by deleting their session data.

3rd Party Apps

  • This applies to any of Django's internal apps or any 3rd party apps you have installed. Just find where the models are and register them in the admin.py file of your project along with any customizations you want to make.

  • Some 3rd party apps may already have an admin.py file with the model registered, so you can find their models in "your" admin page right off the bat but if they don't, you can create a new admin.py file and register the 3rd party models there.

Das ist es 🥸️