pythondjangotwiliosendgridsendgrid-templates

MultiValueDictKeyError on clicking of Unsubscribe in Sendgrid dynamic template


I created on dynamic template for my newsletter app and added custom unsubscribe link and passing uri to template with api in dynamic_template_data but when I click on unsubscribe line it throws error MultiValueDictKeyError at /delete/

Code for ref: models.py

class Newsletter(models.Model):
    created_at = models.DateTimeField(auto_now_add=True)
    updated_at = models.DateTimeField(auto_now=True)
    subject = models.CharField(max_length=150)
    contents = RichTextUploadingField(blank=True, null=True, extra_plugins=
    ['youtube', 'imageresize', ], external_plugin_resources=
                                      [('youtube', '/static/ckeditor/ckeditor/plugins/youtube/', 'plugin.js')])

    def __str__(self):
        return self.subject + " " + self.created_at.strftime("%B %d, %Y")

    def send(self, request):
        contents = self.contents
        uri = request.build_absolute_uri('/delete/')
        subscribers = Subscribers.objects.filter(confirmed=True)
        sg = SendGridAPIClient(settings.SENDGRID_API_KEY)
        template_id = "d-xxxxxxxxxxxxxxxxxx"
        for sub in subscribers:
            message = Mail(
                from_email=settings.FROM_EMAIL,
                to_emails=[sub.subscriber_mail],
                subject=self.subject)

            message.dynamic_template_data = {
                "xar_text": "Join Our Elites Club",
                "uri": uri
            }
            message.template_id = template_id
            sg.send(message)

Views.py

def delete(request):
    sub = Subscribers.objects.get(subscriber_mail=request.GET['email'])
    if sub.subscriber_mail == request.GET['email']:
        sub.delete()
        return render(request, 'frontend/unsubscribed.html', {'email': sub.subscriber_mail, 'action': 'unsubscribed'})
    else:
        return render(request, 'frontend/error.html', {'email': sub.subscriber_mail, 'action': 'denied'})

urls.py

from django.urls import path
from . import views

urlpatterns = [
    path('subscribe/', views.subscribe, name='subscribe'),
    path('delete/', views.delete, name='delete'),
]

Custom Sendgrid template code:

<a href="{{uri}}" style="text-align:center">Unsubscribe</a>

Error:

Internal Server Error: /delete/
Traceback (most recent call last):
  File "C:\Users\ASUS\python_workspace\projects\venv\env\lib\site-packages\django\utils\datastructures.py", line 76, in __getitem__
    list_ = super().__getitem__(key)
KeyError: 'email'

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "C:\Users\ASUS\python_workspace\projects\venv\env\lib\site-packages\django\core\handlers\exception.py", line 47, in inner
    response = get_response(request)
  File "C:\Users\ASUS\python_workspace\projects\venv\env\lib\site-packages\django\core\handlers\base.py", line 181, in _get_response
    response = wrapped_callback(request, *callback_args, **callback_kwargs)
  File "C:\Users\ASUS\python_workspace\projects\news\Newsletter\views.py", line 28, in delete
    sub = Subscribers.objects.get(subscriber_mail=request.GET['email'])
  File "C:\Users\ASUS\python_workspace\projects\venv\env\lib\site-packages\django\utils\datastructures.py", line 78, in __getitem__
    raise MultiValueDictKeyError(key)
django.utils.datastructures.MultiValueDictKeyError: 'email'
[01/Aug/2022 18:34:33] "GET /delete/ HTTP/1.1" 500 76750

Solution

  • It's this line - use get() instead of brackets operator:

    if sub.subscriber_mail == request.GET.get('email')