django.utils.datastructures.MultiValueDictKeyError DJANGO - ajax

I have a form. When I post the form without using ajax, it works well. But when I use the ajax, I have an error like this;
django.utils.datastructures.MultiValueDictKeyError:
My codes are below that without using ajax. It works.
HTML Form:
<form id="add_form" action="/adding/" method="post" enctype="multipart/form-data">
<input type="text" name="title">
<input type="file" name="picture">
<button type="submit" id="send_form" value="ok">Ok</button>
</form>
My views.py codes are:
if request.method == "POST":
title = request.POST.get('title')
pic = request.FILES['picture']
query = Images_Table(title=title, pic=pic)
query.save()
My model codes are:
class Images_Table(models.Model):
title = models.CharField(max_length=70, blank=True, null=True)
pic = models.FileField(upload_to='images_folder', blank=True, null=True)
Until here; everythings are normal, codes works. When I use ajax, I have an error. My HTML Form:
<form id="add_form" method="post" enctype="multipart/form-data">
<input type="text" name="title">
<input type="file" name="picture">
<button id="send_form" value="ok">Ok</button>
</form>
My ajax codes are:
$("#send_form").click(function(){
$.ajax({
url: '/adding/',
method:'post',
data: $("#add_form").serialize(),
headers: '{{ csrf_token }}',
success : function(){
alert('Success posted!');
}
});
});
Error code is below;
django.utils.datastructures.MultiValueDictKeyError: "'picture'"

I solved the problem by changing ajax.
$("#send_form").click(function(){
var file_data = $('#picture').prop('files')[0];
var form_data = new FormData($('form').get(0));
form_data.append('file', file_data);
$.ajax({
url: '/adding/',
method:'post',
cache: false,
contentType: false,
processData: false,
data: form_data,
headers: {'X-CSRFToken': '{{ csrf_token }}'},
success : function(){
alert('Success posted!');
}
});
});

Related

how to request django post method values using ajax

I would like to implement simple django login method using ajax. when i want to retreive html input values using ajax in views, the request.post values are returning None. for ex print(request.POST.get('username')), it returns None.
my html form
<form action="" method="POST">{% csrf_token %}
<input type="text" name="username1" class="form-control rounded-1" id="id_username1" value="">
<input type="password" name="password1" class="form-control rounded-1" id="id_password1" value="">
</div>
<input type="button" id="btnlogin" value='Valider'>
</form>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.6.2/jquery.min.js"></script>
<script>
var token = '{{csrf_token}}';
//login
$('#btnlogin').click(function(){
//alert("/login");
$.ajax({
url: "{% url 'login' %}",
headers:{'X-CSRFToken':token},
method:"POST",
data:{},
dataType: 'json',
success: function (data) {
if (data.status){
console.log('Success');
}
else{
console.log("login failed");
}
}
});
})
</script>
urls.py
path('login/', views.login_page, name='login'),
views.py
def login_page(request):
if request.method == 'POST':
username = request.POST.get('username1')
password = request.POST.get('password1')
print('password :',password)
#result "password : None"
user = authenticate(username=username, password=password)
if user is not None:
login(request, user)
return JsonResponse({'status':True})
else:
return JsonResponse({'status':False})
context = {}
return render(request, 'core/login.html', context)
I do not know where is the error and how to fix this issue.
Thanx in advance.
i tried request.POST['password1']#result None
i changed to GET method. same issue.
I would like to collect forms input values in django view method using ajax

Laravel Ajax update request is duplicating data

i am trying to update data using ajax, but my data is being duplicated,
due to ajax URL, i am not sure if i am passing correctly/
Ajax Code:
jQuery(document).ready(function($) {
$('#update-form').on('submit', function (e) {
e.preventDefault();
$.ajax({
type: "POST",
url: "teachers/" + $('#update-id').attr("value"), //error is here
dataType: 'json',
headers: { 'X-CSRF-TOKEN': $('meta[name="csrf-token"]').attr('content') },
data : $(this).serialize(),
success: function (data) {
alert("updated");
},
});
});
});
view code:
i have table with list of teachers, and edit button for each teacher;
<button type="button" id="btn" value="{{ $teacher->id }}" class="btn btn-primary btn-block btn-sm edit-btn">Edit</button>
in form i have hidden field
<form method="post" id="update-form">
{{ method_field('PATCH') }}
<input type="hidden" id="update-id" value="{{$teacher->id}}" >
<div class="">
<label for="efirst">efirst</label>
<input type="text" class="form-control" name="efirst" id="update-efirst">
<textarea name="esecond" class="form-control" id="update-esecond" rows="6"></textarea>
</div>
<button type="submit" class="btn btn-success" id="update-submit">Update</button>
</form>
when i click on update, teacher ID's are being changed, one teacher id becomes another teacher id. is it correct way to pass teacher id from hidden field?
Write route name like below
At Web.php
Route::post("teacher/{id}/edit","YourController")->name("teacher.update");
At Blade File
$('#update-form').on('submit', function (e) {
e.preventDefault();
var id = $('#update-id').val(); // $('#update-id').attr("value") also ok
$.ajax({
method: "post",
url: "{{ route('teacher.update',id) }}",
dataType: 'json',
headers: { 'X-CSRF-TOKEN': $('meta[name="csrf-token"]').attr('content') },
data : $(this).serialize(),
success: function (data) {
alert("updated");
},
});
});
Try this.
It will be work

Page still refreshing while using ajax with django

I'm using my own custom form. Which looks like:
{%extends 'base_template.html'%}
{%block title%}
<title> Simple Ajax Demo </title>
{%endblock%}
{%block javascript%}
<script>
$(document).ready(function(){
$("#formi").submit(function(event){
$.ajax({
type:"POST",
url:"{% url 'haha:ajax' %}",
data: {
username : $('#username').val(),
password : $('#password').val(),
csrfmiddlewaretoken: {% csrf_token %},
},
success: function(data){
alert('asdas');
},
});
});
});
</script>
{%endblock%}
{%block content%}
<div>
<form method="post" id="formi">
{%csrf_token%}
Username:<input type="text" id="username"><br>
Password:<input type="text" id="password"><br>
<button type="submit">Click Me</button>
</form>
</div>
{%endblock%}
I've got two input fields with name password and username, to be saved to the table User.
View.py
def ajax(request):
if request.method == 'POST':
username = request.POST['username']
password = request.POST['password']
Users.objects.create(username=username, password=password)
return render(request,'core/ajax.html')
I've tried with the GET method too. But still the page gets refreshed. Also tried firing the Ajax call while clicking the button, but it says something like multiple-dict value error. Also tried with
username = request.POST.get('username')
password = request.POST.get('password')
Edit onSubmit event as
$("#formi").submit(function(event){
event.preventDefault();
$.ajax({
/* you have type here change it to method */
method:"POST",
url:"{% url 'haha:ajax' %}",
data: {
username : $('#username').val(),
password : $('#password').val(),
csrfmiddlewaretoken: {% csrf_token %},
},
success: function(data){
alert('asdas');
},
});
}
It is the default behaviour of onSubmit to refresh the page whenever we submit the form. By event.preventDefault(); we are pausing that default behaviour.
Just modified the jquery code, works well!! Here's a code:
{%extends 'base_template.html'%}
{%block title%}
<title> Simple Ajax Demo </title>
{%endblock%}
{%block javascript%}
<script>
$(document).on('submit','#formi',function(event){
event.preventDefault();
$.ajax({
method:"POST",
url:"{%url 'haha:ajax'%}",
data: {
username : $('#username').val(),
password : $('#password').val(),
csrfmiddlewaretoken:$('input[name=csrfmiddlewaretoken]').val()
},
success: function(data){
alert('asasd');
},
});
});
</script>
{%endblock%}
{%block content%}
<div>
<form id="formi" method="post">
{%csrf_token%}
Username:<input type="text" name="username" id="username"><br><br>
Password:<input type="text" name="password" id="password"><br><br>
<input type="submit" value="Click Me"><br>
</form>
</div>
{%endblock%}
But i don't understand why is document.on('submit','#formi'){} is working?

File Data is blank array in server side: Laravel 5.3

I am trying to post File using JQuery. Below is my code.
<script language="javascript">
$(document).ready(function() {
$('#frmUpdateProfile').on("submit", function(event) {
event.stopPropagation(); // Stop stuff happening
event.preventDefault(); // Totally stop stuff happening
var data = {
"FileName" : event.target.FileName.files,
"_token" : "{!! csrf_token() !!}"
};
$.ajax({
url: '{{URL::route("UpdateProfile")}}',
method: "POST",
async: true,
data: JSON.stringify(data),
processData: false,
contentType: "application/json; charset=utf-8",
success: function (msg) {
SuccessCallback(msg);
},
error: function (jqXHR) {
ErrorCallback(jqXHR);
}
});
});
});
</script>
I tried processData: false,. While debugging in Js, you can check that image is coming in the data. Below is the screenshot.
But when I print the request data in Laravel, it show blank array.
Html form is here
<form method="POST"
action="http://localhost:1234/AS6-Code/public/UpdateProfile"
accept-charset="UTF-8"
enctype="multipart/form-data"
id="frmUpdateProfile">
<input name="_token" type="hidden" value="26KWkWdNqe5iOFE8VRBf1dRnL5xKxwN25jg3tAFW">
<input type="hidden" name="_token" value="26KWkWdNqe5iOFE8VRBf1dRnL5xKxwN25jg3tAFW">
<input multiple="1" name="FileName" type="file">
<input class="btn btn-info" type="submit" value="Update">
</form>
Am I doing something wrong?
Try sending your request with FormData instead:
var data = new FormData($('#frmUpdateProfile')[0]);
Also set contentType to false:
contentType: false
Also Update
event.target.FileName.files
to
event.target.FileName.files[0]
event.target.FileName.files is a FileList object. I believe you need event.target.FileName.files[0] instead.

input(file) and input (text) send with one ajax

html
<body>
<form method="post" action="" id="dataForm" enctype="multipart/form-data">
<input type="text" id="textSelector"/>
<input type="file" id="fileSelector"/>
<button name="sub-comfirm" class="btn-selection-content" type="submit" id="sub-comfirm">Send</button>
</form>
</body>
js/ajax
var fileVar = null;// global var to store file info
$(document).ready(function(){
$('#dataForm').on('submit', function(e) {
e.preventDefault();
SendData();
});
$('#fileSelector').on('change',function(ev){
fileVar = null;
fileVar = new FormData();
$.each(ev.target.files, function(key, value)
{
fileVar.append(key, value);
});
});
});
function SendData(){
var formData = new FormData($("#dataForm")[0]);
// should i add the filerVar like this ?
// formData.append("Image", fileVar);
$.ajax({
type: "POST",
url: "checkinput.php",//you need to add this '?files part' to URL
data: formData,// use fileVar here now
cache: false,
processData: false,
// contentType: false,
success:function(data)
{
console.log(data);
console.log("success");
},
error: function(jqXHR, textStatus, errorThrown)
{
console.log("failure");
}
});
}
php
print_r($_POST);
print_r($_FILES);
my intention is to send input(file) and input(text) in one ajax , i can get the input file value if i add ajax data with fileVar , but i cant get my input text value i have no idea why , can anyone tell me what i did wrong ?
var formData = new FormData($("#dataForm")[0]) is the way to get both to one ajax but i cant get any input text value.
anyone can teach me how to make this work ?
I think you need to specify input name attributes:
<body>
<form method="post" action="" id="dataForm" enctype="multipart/form-data">
<input type="text" id="textSelector" name="textSelector"/>
<input type="file" id="fileSelector" name="fileSelector"/>
<button name="sub-comfirm" class="btn-selection-content" type="submit" id="sub-comfirm">Send</button>
</form>
</body>
Hope that helps.

Resources