How to add button or link to Admin page and assign an action to it ?

I would like to customize Admin page for my NewsletterSubscriber model.

How can I add new button (just beside the “ADD NEWSLETTER SUBSCRIBER +”) and assign specific action to this button ?

The idea behind is that I would like to have functionality to export string (and show it to user with HttpResponse) with multiple email addresses separated by comma (later I’ll be pasting this string directly into TO field when sending emails).

I already tried to implement this using Django Admin Actions but unfortunately I’m getting WARNING: Items must be selected in order to perform actions on them. No items have been changed.
So if this would be easier, for me the option is also to bypass this WARNING - if that’s possible.
But I don’t want to make selections to perform this action because I don’t use queryset and I don’t care about selected items but I use specific query to retrieve needed objects for exporting.

Here is what I tried to do using Django Admin Actions:

def export_newsletter_subscribers(modeladmin, request, queryset):
    emails = []
    ns = NewsletterSubscriber.objects.filter(has_consented=True)
    for n in ns:
        emails.append(n.email)
    emails_string = ","
    emails_string = emails_string.join(emails)
    response = HttpResponse(emails_string)
    return response
export_newsletter_subscribers.short_description = "Export Newsletter Subscribers"

I’m not sure I understand what you’re looking to do.

First, Django actions are designed for a specific purpose. From the docs:

In these cases, Django’s admin lets you write and register “actions” – functions that get called with a list of objects selected on the change list page.

If you’re just looking to display a list of names, that’s not an admin function, that’s an ordinary view. Likewise, the functionality of building and sending an email based upon user interactions - that’s a standard view, too.

From the Admin docs:

The admin’s recommended use is limited to an organization’s internal management tool. It’s not intended for building your entire front end around.

and

If you need to provide a more process-centric interface that abstracts away the implementation details of database tables and fields, then it’s probably time to write your own views.

It’s a common mistake to try and build everything around the admin. You’ll likely save time in the long run by not trying to wedge everything in to it.

Ken

Yes, I understand this is bad practice but for me it would be too much effort to build separate Admin panel only because of 2-3 additional functionalities :slightly_smiling_face:.

That’s why I came up with a workaround.
I created separate model NewsletterSubscriberExport with field export which is auto populated with the exported string - I can then just copy the string with or without saving the model.

class NewsletterSubscriberExport(models.Model):
    export = models.TextField(default=export_newsletter_subscribers_emails)