Passing context to django admin index page

Viewed 1129

I'm trying to create a table on django admin's index page, listing all users registered in a specific timeframe. I've managed to already edit the index page to include my table but I now want to populate the table. I tried declaring the extra_context variable but it still doesn't pass it to the template. I've been on this issue for days and still can't figure out what I'm doing wrong. This is my admin.py file

from django.contrib import admin
from django.contrib.auth.models import Group
from django.contrib.auth.admin import UserAdmin
from .forms import SignUpForm, EditUserForm
from .models import CustomUser
from django.urls import path
from datetime import datetime, timedelta
from django.utils import timezone


class CustomUserAdmin(UserAdmin):
    list_filter = ['created_at',]
    list_display = ['username', 'email', 'created_at', 'is_active']
    # index_template = 'admin/my_index.html'

    def time_threshold(num):
        num = int(num)
        thresh = datetime.now(tz=timezone.utc) - timedelta(hours=num)
        return thresh


    print(time_threshold(30))       
    def get_urls(self):
        urls = super().get_urls()
        custom_urls = [
            path("user_metrics/", self.user_metrics),
        ]
        return custom_urls + urls

    def user_metrics(self, request, extra_context=None):
        extra_context = extra_context or {}
        user_24 = CustomUser.objects.filter(created_at__gt=time_threshold(730))
        extra_context['users_in_past_24_hours'] = CustomUser.objects.filter(created_at__gt=time_threshold(24))
        extra_context['users_in_past_week'] = CustomUser.objects.filter(created_at__gt=time_threshold(168))
        extra_context['users_in_past_month'] = CustomUser.objects.filter(created_at__gt=time_threshold(730))
        print(user_24)
        return super(CustomUserAdmin, self).user_metrics(request, extra_context=extra_context)


admin.site.register(CustomUser, CustomUserAdmin)
admin.site.unregister(Group)
admin.site.site_header = "Savests Custom Admin"

And this is my index.html file I have inside template/admin folder

{% extends "admin/base_site.html" %}
{% load i18n static %}

{% block extrastyle %}{{ block.super }}<link rel="stylesheet" type="text/css" href="{% static "admin/css/dashboard.css" %}">{% endblock %}

{% block coltype %}colMS{% endblock %}

{% block bodyclass %}{{ block.super }} dashboard{% endblock %}

{% block breadcrumbs %}{% endblock %}

{% block nav-sidebar %}{% endblock %}

{% block content %}
<div id="content-main">
  {% include "admin/app_list.html" with app_list=app_list show_changelinks=True %}
</div>

<div>
    <h5>Users in the last 24 hours</h5>
        <table class="table table-hover table-bordered">
            <caption>User Information</caption>
            <thead class="thead-dark">
                <th>User ID</th>
                <th>Username</th>
                <th>Email Address</th>
                <th>Active Status</th>
                <th>Staff Status</th>
            </thead>
            {% for a in users_in_past_24_hours %}
                <tr>
                    <td>{{ a.id }}</td>
                    <td>{{ a.username }}</td>
                    <td>{{ a.email }}</td>
                    <td>
                        {% if a.is_active %}
                            <form action="{% url 'toggle_user_status_false' user_id=a.id %}" method="post">
                                {% csrf_token %}
                                    <button class="btn btn-danger" type="submit">
                                        Deactivate
                                    </button>
                            </form>
                        {% else %}
                            <form action="{% url 'toggle_user_status_true' user_id=a.id %}" method="post">
                                {% csrf_token %}
                                    <button class="btn btn-primary" type="submit">
                                        Activate
                                    </button>
                            </form>
                        {% endif %}
                    </td>
                    <td>
                        {% if a.is_staff %}
                            Staff
                        {% else %}
                            Not Staff
                        {% endif %}
                    </td>
                </tr>
            {% endfor %}
        </table>
        <br>
        <hr>

        <h5>Users in the past week</h5>
        <table class="table table-hover table-bordered">
            <caption>User Information</caption>
            <thead class="thead-dark">
                <th>User ID</th>
                <th>Username</th>
                <th>Email Address</th>
                <th>Active Status</th>
                <th>Staff Status</th>
            </thead>
            {% for a in users_in_past_week %}
                <tr>
                    <td>{{ a.id }}</td>
                    <td>{{ a.username }}</td>
                    <td>{{ a.email }}</td>
                    <td>
                        {% if a.is_active %}
                            <form action="{% url 'toggle_user_status_false' user_id=a.id %}" method="post">
                                {% csrf_token %}
                                    <button class="btn btn-danger" type="submit">
                                        Deactivate
                                    </button>
                            </form>
                        {% else %}
                            <form action="{% url 'toggle_user_status_true' user_id=a.id %}" method="post">
                                {% csrf_token %}
                                    <button class="btn btn-primary" type="submit">
                                        Activate
                                    </button>
                            </form>
                        {% endif %}
                    </td>
                    <td>
                        {% if a.is_staff %}
                            Staff
                        {% else %}
                            Not Staff
                        {% endif %}
                    </td>
                </tr>
            {% endfor %}
        </table>
        <br>
        <hr>

        <h5>Users in the past month</h5>
        <table class="table table-hover table-bordered">
            <caption>User Information</caption>
            <thead class="thead-dark">
                <th>User ID</th>
                <th>Username</th>
                <th>Email Address</th>
                <th>Active Status</th>
                <th>Staff Status</th>
            </thead>
            {% for a in users_in_past_month %}
                <tr>
                    <td>{{ a.id }}</td>
                    <td>{{ a.username }}</td>
                    <td>{{ a.email }}</td>
                    <td>
                        {% if a.is_active %}
                            <form action="{% url 'toggle_user_status_false' user_id=a.id %}" method="post">
                                {% csrf_token %}
                                    <button class="btn btn-danger" type="submit">
                                        Deactivate
                                    </button>
                            </form>
                        {% else %}
                            <form action="{% url 'toggle_user_status_true' user_id=a.id %}" method="post">
                                {% csrf_token %}
                                    <button class="btn btn-primary" type="submit">
                                        Activate
                                    </button>
                            </form>
                        {% endif %}
                    </td>
                    <td>
                        {% if a.is_staff %}
                            Staff
                        {% else %}
                            Not Staff
                        {% endif %}
                    </td>
                </tr>
            {% endfor %}
        </table>
        <br>
        <hr>
</div>
{% endblock %}

{% block sidebar %}
<div id="content-related">
    <div class="module" id="recent-actions-module">
        <h2>{% translate 'Recent actions' %}</h2>
        <h3>{% translate 'My actions' %}</h3>
            {% load log %}
            {% get_admin_log 10 as admin_log for_user user %}
            {% if not admin_log %}
            <p>{% translate 'None available' %}</p>
            {% else %}
            <ul class="actionlist">
            {% for entry in admin_log %}
            <li class="{% if entry.is_addition %}addlink{% endif %}{% if entry.is_change %}changelink{% endif %}{% if entry.is_deletion %}deletelink{% endif %}">
                {% if entry.is_deletion or not entry.get_admin_url %}
                    {{ entry.object_repr }}
                {% else %}
                    <a href="{{ entry.get_admin_url }}">{{ entry.object_repr }}</a>
                {% endif %}
                <br>
                {% if entry.content_type %}
                    <span class="mini quiet">{% filter capfirst %}{{ entry.content_type.name }}{% endfilter %}</span>
                {% else %}
                    <span class="mini quiet">{% translate 'Unknown content' %}</span>
                {% endif %}
            </li>
            {% endfor %}
            </ul>
            {% endif %}
    </div>
</div>
{% endblock %}
1 Answers

1st way is to declare subclass django.contrib.admin.site.AdminSite() and override the .index() method in admin.py

class MyAdminSite(django.contrib.admin.site.AdminSite):
    def index(self, request, extra_context=None):
        if extra_context is None:
            extra_context = {}
        user_24 = CustomUser.objects.filter(created_at__gt=time_threshold(730))
        extra_context['users_in_past_24_hours'] = CustomUser.objects.filter(created_at__gt=time_threshold(24))
        extra_context['users_in_past_week'] = CustomUser.objects.filter(created_at__gt=time_threshold(168))
        extra_context['users_in_past_month'] = CustomUser.objects.filter(created_at__gt=time_threshold(730))
        extra_context["app_list"] = get_app_list_in_custom_order()
        return super(MyAdminSite, self).index(request, extra_context)

then you should register your site admin (also in admin.py) my_admin_site = MyAdminSite(name='myadmin') when you create your own AdminSite you need to register all models using it, so instead of admin.site.register(YourModel) you should use my_admin_site.register(YourModel) for all models you use. you also need to add path to your adminsite in urls.py

from pathtoyouradmin.admin import my_admin_site


urlpatterns = [
...
    path('admin/', my_admin_site.urls),
...
]

you can solve your problem other way. you can create contextprocessor where you check path of current page and if it admin index then provide needed extra_context

def context_users_info(request):
    extra_context = {}
    if request.path == 'index admin page'# you need to put path to your index admin page
        user_24 = CustomUser.objects.filter(created_at__gt=time_threshold(730))
        extra_context['users_in_past_24_hours'] = CustomUser.objects.filter(created_at__gt=time_threshold(24))
        extra_context['users_in_past_week'] = CustomUser.objects.filter(created_at__gt=time_threshold(168))
        extra_context['users_in_past_month'] = CustomUser.objects.filter(created_at__gt=time_threshold(730))
        extra_context["app_list"] = get_app_list_in_custom_order()
    return extra_context

and don't forget to register your context processor in settings.py

Related