[Django]-Call a function with a button in django admin

3๐Ÿ‘

โœ…

You can use get_urls method and create a custom view method of the ScenarioAdmin.

models.py:

from django.utils.html import format_html
from django.urls import reverse_lazy

class Scenario(TemporalObject):
    ...

    def activate_button(self):
        return format_html('<a href="{}" class="link">Activate</a>',
            reverse_lazy("admin:admin_activate_scenario", args=[self.pk])
        )

admin.py:

from django.template.response import TemplateResponse
from django.urls import path
from django.shortcuts import redirect, get_object_or_404


class ScenarioAdmin(admin.ModelAdmin):
    list_display = (
        "name", "user", "start", 
        "end", "nb_hours", "activate_button")

    def get_urls(self):
        urls = super().get_urls()
        my_urls = [
            path('activate-scenario/<int:pk>/', self.acitvate_scenario, name="admin_activate_scenario"),
        ]
        return my_urls + urls

    def acitvate_scenario(self, request, pk):
        # ...
        context = dict(
           # Include common variables for rendering the admin template.
           self.admin_site.each_context(request),
           # Anything else you want in the context...
        )

        # Get the scenario to activate
        target = get_object_or_404(Scenario, pk=pk)
        # It is already activated
        if target.user == request.user.username:
            msg = "Scenario already active"
            self.message_user(request, msg, level=messages.WARNING)
            return redirect(request.META.get('HTTP_REFERER'))
        if target.user is not None and len(target.user) > 0:
            msg = f"Can't activate scenario '{target}'"
            msg += f" because it is active for user '{target.user}'"
            self.message_user(request, msg, level=messages.ERROR)
            return redirect(request.META.get('HTTP_REFERER'))
        # Deactivate all other scenarios that are active
        for scenario in Scenario.objects.filter(user=request.user.username):
            scenario.user = ""
            scenario.save()
        # Activate the scenario
        target.user = request.user.username
        target.save()
        msg = f"Activated scenario '{target}'"
        self.message_user(request, msg, level=messages.INFO)

        # redirect or TemplateResponse(request, "sometemplate.html", context)
        return redirect(request.META.get('HTTP_REFERER'))
๐Ÿ‘คNKSM

0๐Ÿ‘

You can simply add a action button like this:

def activate_button(modeladmin, request, queryset):
    for scenario queryset:
        #Do something
        pass

class ScenarioAdmin(admin.ModelAdmin):
    list_display = ("name", "user", "start", "end", "nb_hours")
    actions = [activate_button]

admin.site.register(Scenario, ScenarioAdmin)

You can find it in the docs here:
https://docs.djangoproject.com/en/3.1/ref/contrib/admin/actions/

๐Ÿ‘คjojacobsen

Leave a comment