Django Admin Action Function Failing - emailing multiple selected users (if "apply" in request.POST)
My implementation uses a CustomUser model. I'm creating a Django admin action that allows me to compose and send emails to multiple users. Everything on the website behaves as though it's working. After I hit the Send Email button, I'm redirected back to the Admin but I see no console output indicating an email was sent and self.message_user is never called and sent to the Admin.
Email Backend
Password Reset works with reset link sent to the console, so email backend is working.
EMAIL_BACKEND = "django.core.mail.backends.console.EmailBackend"
admin.py
if "apply" in request.POST: <-- This line never fires!
class CustomUserAdmin(ExportMixin, UserAdmin):
@admin.action(description="Email selected users")
def send_email_action(self, request, queryset):
print(request.POST)
print(request.POST.getlist("apply"))
input("HALT")
if "apply" in request.POST:
print("apply")
form = EmailForm(request.POST)
if form.is_valid():
print("form valid")
subject = form.cleaned_data["subject"]
message = form.cleaned_data["message"]
recipients = [user.email for user in queryset]
send_mail(subject, message, "your_email@example.com", recipients)
self.message_user(request, f"{len(recipients)} emails were sent.")
return HttpResponseRedirect(request.get_full_path())
else:
print("no apply")
form = EmailForm()
return render(request, "email/admin_send.html", {"form": form})
forms.py
Works as expected.
class EmailForm(forms.Form):
subject = forms.CharField(max_length=256)
message = forms.CharField(widget=forms.Textarea)
admin_send.html
Either:
- The send_email_action function is getting called after I hit the Send Email button but the form isn't sending back the "apply" data, so this is failing: if "apply in request.POST:
- --OR--
- The send_email_action function isn't even getting called again because I don't know how to make that happen, maybe that has something to do with this: form action=""
Q1: Do I need to define the form action="" which is currently blank? I ask because it sort of feels like when I click the Send Email button, it may not be calling the send_email_action function again. If I need to define this, I don't know what to put here because normally it would be a URL but I need it to be an admin action function. I believe this is the primary problem because if the function were getting called, I should see the results of print(request.POST) printed to the console again, but I don't (ie: QueryDict).
Q2: Notice the input name="apply". The send_email_action function is obviously looking for this data, but it doesn't come back from the form or if it does, I cannot find it in the request object. I believe this may also be a problem, but we can only solve it after we solve the first problem above.
{% extends "base.html" %}
{% load crispy_forms_tags %}
{% block title %}
Email Users
{% endblock %}
{% block content %}
<br>
<br>
<br>
<h2>Email Users</h2>
<form action="" method="post">
{% csrf_token %}
{{ form|crispy }}
<input type="submit" name="apply" value="Send Email">
</form>
{% endblock content %}
Step1) In the Admin I've selected multiple users in my CustomUser table, I've selected "Email selected users" from the action dropdown menu, I've clicked GO:
console
<QueryDict: {'csrfmiddlewaretoken': ['zHlbmtRaNIFwrdNmCFxwyiVLi1IaCFKHoJAmZWKttwTMN97gC1JhWSryO9POuaDK'], 'action': ['send_email_action'], 'select_across': ['0'], 'index': ['0'], '_selected_action': ['6', '1', '7', '8']}>
[]
HALT
Step2) I hit enter in the console to continue, the form displays. I enter a subject and a message.
console
no apply
[23/Nov/2024 23:58:25] "POST /admin/app_accounts/customuser/?company=Cisco HTTP/1.1" 200 10317
Step3) I click the "Send Email" button.
console
[24/Nov/2024 00:02:07] "POST /admin/app_accounts/customuser/?company=Cisco HTTP/1.1" 200 19098
[24/Nov/2024 00:02:07] "GET /admin/jsi18n/ HTTP/1.1" 200 3342