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
CodePudding user response:
It's this line - use get() instead of brackets operator:
if sub.subscriber_mail == request.GET.get('email')
CodePudding user response:
Resolved answer posted by @vinkomlacic works, I missed adding handelbar for email in sendgrid template and passing it in my API, so:
message.dynamic_template_data = {
"xar_text": "Join Our Elites Club",
"uri": uri,
"sub_email": sub.subscriber_mail
}
in sendgrid template: <a href="{{ uri }}?email={{ sub_email }}" style="text-align:center">Unsubscribe</a>
.