Getting a django.utils.datastructures.MultiValueDictKeyError using ajax
I am trying to use the ajax post function to post data from my contact form in one of my templates. However, I am getting a 'django.utils.datastructures.MultiValueDictKeyError' when I make the request.
The error is a server error and it is displayed as shown
django.utils.datastructures.MultiValueDictKeyError: 'name'
It is being triggered in the view.py folder on the line with the code
name = request.POST['name']
Here is my model for the message:
class Message(models.Model):
name = models.CharField(max_length=255)
email = models.CharField(max_length=255)
content = models.TextField(max_length=10000)
created_at = models.DateTimeField(auto_now_add=True)
This is my view.py:
def save_message(request):
if request.method=='POST':
name = request.POST['name']
email = request.POST['email']
content = request.POST['content']
Message.objects.create(
content = content,
name = name,
email = email
)
messages.success(request, f'Your message has been sent. Expect a response soon!')
return JsonResponse({'bool':True})
This is the form in the index template
{% csrf_token %}
<form class="contactForm" id="contactForm">
<div class="form-floating">
<input class="form-control" class="message-name" id="name" type="text" placeholder="Enter your name..." />
</div>
<div class="form-floating">
<input class="form-control" class="message-email" id="email" type="email" placeholder="Enter your email..." />
</div>
<div class="form-floating">
<textarea class="form-control" id="message" class="message-text" placeholder="Enter your message here..."></textarea>
</div>
<br />
<button class="btn btn-primary text-uppercase save-message" id="submitButton" type="submit">Send</button>
</form>
And this is my ajax:
{% block script %}
<script>
$(document).ready(function(){
// This is for the post messages for non-logged in users
$(".save-message").on('click',function(){
var _content=$(".message-text").val();
var _messageName=$(".message-name").val();
var _messageEmail=$(".message-email").val();
// Ajax
$.ajax({
url:"/save-message",
type:"POST",
data:{
content:_content,
name:_messageName,
email:_messageEmail,
csrfmiddlewaretoken:"{{csrf_token}}"
},
dataType:'json',
beforeSend:function(){
$(".save-message").addClass('disabled').text('Saving...');
},
success:function(res){
if(res.bool==true){
$(".message-text").val('');
}
$(".save-message").removeClass('disabled').text('submit');
}
});
});
});
</script>
{% endblock %}
Using request.POST[]
is for data sent with regular HTML forms, but not when sending data using AJAX (even if it is sent via POST). To access that you need the raw, request.body
, and to parse that you need json
, which also means you need to import json
:
import json
def save_message(request):
if request.method=='POST':
data = json.loads(request.body)
name = data['name']
email = data['email']
content = data['content']
Message.objects.create(
content = content,
name = name,
email = email
)
messages.success(request, f'Your message has been sent. Expect a response soon!')
return JsonResponse({'bool':True})
The error would have occurred with email = request.POST['email']
or content = request.POST['content']
because request.POST
is empty, so the keys, name
, email
, content
, or any other key would have raised the MultiValueDictKeyError:
.
Source: Django Docs:
HttpRequest.body
The raw HTTP request body as a bytestring. This is useful for processing data in different ways than conventional HTML forms: binary images, XML payload etc. For processing conventional form data, use HttpRequest.POST.