mrtexaz
mrtexaz

Reputation: 661

Django 2 add custom button to admin

using Django 2.1.4, its admin site and ModelAdmin.

I would like to add a custom button in the model list, near each item, as in the picture.

Clicking on a button should open a custom view.

To achieve that, I am adding an url in ModelAdmin.

The issue is that, when clicking on the "Generate preview" button, the view is not invoked but rather I get an error message, i.e. "Questionario istituzione scolastica with ID "419/gen_pdf_preview" doesn't exist. Perhaps it was deleted?".

http log from Django reports code 302, for the request:

[19/Dec/2018 09:16:54] "GET /en/admin/vision/questionarioistituzionescolastica/419/gen_pdf_preview/ HTTP/1.1" 302 0 
[19/Dec/2018 09:16:55] "GET /en/admin/vision/questionarioistituzionescolastica/419/gen_pdf_preview/change/ HTTP/1.1" 302 0

I have tried two approaches, but both do not work yet:

1 - a view inside the extended ModelAdmin

2 - an external view

Here is the custom ModelAdmin, from admin.py:

from .models import * 
from .views import serve_pdf_preview 
from django.utils.html import format_html

@admin.register(QuestionarioIstituzioneScolastica) 
class QuestionarioIstituzioneScolasticaAdmin(admin.ModelAdmin):

    list_display = ('denominazione_istituzione_scolastica', 'generate_pdf_preview_html')

    def generate_pdf_preview_html(self, obj):
        return format_html('<a class="button" href="%s/gen_pdf_preview/">Generate preview</a>' % obj.id)

    generate_pdf_preview_html.short_description = 'Generate pdf preview'
    generate_pdf_preview_html.allow_tags = True

    def get_urls(self):
        from django.urls import path

        urls = super().get_urls()
        urls += [
            # path('<path:object_id>/gen_pdf_preview/', self.admin_site.admin_view(self.generatepdf_view), name='vision_questionarioistituzionescolastica_generatepdf')
            path('<path:object_id>/gen_pdf_preview/', self.admin_site.admin_view(serve_pdf_preview),
                 name='vision_questionarioistituzionescolastica_generatepdf')
        ]

        for u in urls:
            print(u)

        return urls

    # also tried this way, but it does not work either
    def generatepdf_view(self, request, object_id, form_url='', extra_context=None):
        print("generatepdf_view {0}".format(str(object_id)))
        pass

The external view is simply:

def serve_pdf_preview(request, id):
    print("views.serve_pdf_preview")
    return HttpResponse("pdf render")

with its urlpattern:

urlpatterns = [
   ...
   path('<int:pk>/gen_pdf_preview/', views.serve_pdf_preview)
   ...

any clues?

enter image description here

Upvotes: 1

Views: 1040

Answers (1)

not2acoder
not2acoder

Reputation: 1162

Everything seems fine, just append the custom url before the admin urls in get_urls method as:

urls = super().get_urls()
custom_urls  += [
        # path('<path:object_id>/gen_pdf_preview/', self.admin_site.admin_view(self.generatepdf_view), name='vision_questionarioistituzionescolastica_generatepdf')
        path('<path:object_id>/gen_pdf_preview/', self.admin_site.admin_view(serve_pdf_preview),
             name='vision_questionarioistituzionescolastica_generatepdf')
    ]

return custom_urls + urls

Upvotes: 2

Related Questions