Flask: POST request using AJAX - python

I want to make a post request by using ajax. I want to use the input value as function parameter and append the function return into a html table. I don't know but a think that my code is wrong and the ajax is not working.
Note: For testing, I'm taking input value and returning to html page.
network.html
<script type="text/javascript">
$(function(){
$('#button').click(function(){
var dados = $('#search-input').val();
$.ajax({
url: '/network',
data: $('form').serialize(),
type: 'POST',
success: function(data){
$('#result').append(data)
console.log(data);
},
error: function(error){
console.log(error);
}
});
});
});
</script>
<form name='form' method="POST">
<input type="text" name="search-input" id="search-input" class="form-control" placeholder="Users and ID" >
<button type="submit" class="btn btn-primary" id="button">Search</button>
</form>
<span id=result>{% print dado %}</span>
app.py
#app.route('/network',methods=['POST','GET'])
def network():
if request.method == 'POST':
input = request.form['search-input']
return render_template('network.html',dado=input)
else:
return render_template('network.html',dado='')
Edit: After this update what's returning is a JSON format
{
"dado": "INPUT VALUE"
}
app.py
#app.route('/network',methods=['POST','GET'])
def network():
if request.method == 'POST':
input = request.form['search-input']
return jsonify(dado=input)
else:
return render_template('network.html',dado='')
network.html
<script type="text/javascript">
$(function(){
$('#botao').click(function(){
var dados = $('#search-input').val();
$.ajax({
url: "{{ url_for('network') }}",
data: JSON.stringify(dados),
contentType: 'application/json;charset=UTF-8',
type: 'POST',
success: function(data){
$('#result').append(data["dado"])
console.log(data);
},
error: function(error){
console.log(error);
}
});
});
});
</script>

You got to return JSON!
Instead of return render_template(...), use:
return jsonify(dado = input)
Then in your ajax success call:
success: function(data){
$('#result').append(data["dado"])
console.log(data);
}
...
}); // end AJAX
e.preventDefault();
Don't forget to import jsonify
from flask import jsonify

Related

How to send data to the view in Flask using AJAX?

Please help...
I am trying to upload a csv or excel file, and using an Ajax call trying to send it to Flask along with an integer.
HTML Form:
<form id="testFileForm" method="POST" action="{{ url_for('auto') }}" enctype="multipart/form-data">
{{ fileUploadForm.csrf_token }}
<label class="connect choosefile setInput config-button-size " >
<i class="fa fa-file" aria-hidden="true"></i>
<span id="testFileLabel">Choose Test Data</span>
{{ fileUploadForm.file(class="input1 btn btn-primary", id="testFile") }}
</label>
<label class="form-label" style="padding-left:10px ;">
<input class="btn btn-primary config-button-size" id="testFilebtn" type="submit" value="Process">
</label>
</form>
Ajax Call:
$('#testFilebtn').click(function() {
var file = document.getElementById("testFile").files[0];
alert(file)
var data = {
file: file,
id : 1
}
alert('file loaded')
$.ajax({
data: data,
type: "POST",
url: "auto",
"Content-Type": 'application/json',
dataType: 'json',
success: function(response) {
alert(response)
},
});
});
View:
#app.route('/auto', methods=['POST', 'GET'])
#login_required
def auto(dataset_id=None):
fileUploadForm = FileUploadForm()
if request.method=='POST' and fileUploadForm.validate_on_submit():
try:
file = request.files['file']
id = request.form['id']
print('id')
print(id)
except UploadNotAllowed:
return redirect(url_for("auto"))
# return redirect(url_for("auto"))
return "te"
I get error while retrieving the id, which indicates I am also not receiving file from ajax call.
Error:
werkzeug.exceptions.BadRequestKeyError: 400 Bad Request: The browser (or proxy) sent a request that this server could not understand.
KeyError: 'id'
I am new to Ajax calls, some help would highly be appreciated...
I believe you could do it like this :
var fd = new FormData($('#testFileForm')[0]);
fd.append( 'id', 1 );
$.ajax({
url: 'http://example.com/',
data: fd,
processData: false,
contentType: false,
type: 'POST',
success: function(data){
alert(data);
}
});
Notes:
Setting processData to false lets you prevent jQuery from automatically transforming the data into a query string.
See the docs for more info.
Setting the contentType to false is imperative, since otherwise jQuery will set it incorrectly.

Posting file upload via AJAX returns empty dictionary on Flask side

I have a Flask app that was working until I added login functionality. The issue I'm having is I have a modal that the user can upload a file with.
HTML
<p>Upload Photo</p>
<form method="POST" name="upload_pic" id="upload_pic" enctype="multipart/form-data">
<input type="file" class="custom-file-input" name="exampleInputFile" id="exampleInputFile" aria-describedby="fileHelp">
<label class="custom-file-label" for="exampleInputFile">
Select file...
</label>
<button type="button" class="btn btn-success" data-dismiss="modal" id="AddNotesSubmit">Submit</button>
Then an AJAX call to upload the file:
// add notes post
$('#AddNotesSubmit').on('click', function(e) {
var notes = $("#note_text").val();
var schedule_id = $("#noteSchID").text();
console.log(notes);
e.preventDefault();
$.ajax({
type: "POST",
url: "/",
data: { AddNotes: "", schedule_id: schedule_id, notes: notes },
success:function(response){
$('#response').text(JSON.stringify(response));
}
});
var fullPath = $("#exampleInputFile").val();
var filename = fullPath.replace(/^.*[\\\/]/, '');
const form = $('#upload_pic')[0];
const pic = new FormData(form);
console.log(form);
console.log(pic);
console.log(filename);
if (filename != '') {
$.ajax({
type: "POST",
url: "/upload_pic",
data: pic,
processData: false, // tell jQuery not to process the data
contentType: false // tell jQuery not to set contentType
});
}
$('#modalAddNotes').modal('hide');
});
});
And finally the Flask code I'm using to debug:
#app.route('/upload_pic', methods=['POST'])
def upload_pic():
print(' request.files: %s' %request.files)
files = request.files.get('files[]')
print(' files: %s' %files)
The command line output on the python side is:
request.files: ImmutableMultiDict([])
files: None
So it's returning an empty dictionary. Previously, when I used:
uploaded_pic = request.files['exampleInputFile']
It worked, but now with that code included it throws a 400 error because the 'exampleInputFile' is invalid key in the request.files dictionary. I removed the #login_required from the route and it didn't change anything.
From my point of view, it is difficult to see why your code is not working. In your example, the form tag is not closed. Also, you didn't describe how your javascript code is executed. Although I assume that you are using a click event, I tested your code with a submit event. I have come to the conclusion that the code works.
Here is the variant I used for testing:
<p>Upload Photo</p>
<form method="POST" name="upload_pic" id="upload_pic" enctype="multipart/form-data">
<input type="file" class="custom-file-input" name="exampleInputFile" id="exampleInputFile" aria-describedby="fileHelp">
<label class="custom-file-label" for="exampleInputFile">
Select file...
</label>
<button type="submit" class="btn btn-success" data-dismiss="modal" id="AddNotesSubmit">Submit</button>
</form>
<script
src="https://code.jquery.com/jquery-3.6.0.min.js"
integrity="sha256-/xUj+3OJU5yExlq6GSYGSHk7tPXikynS7ogEvDej/m4="
crossorigin="anonymous"></script>
<script type="text/javascript">
$(document).ready(function() {
$('form[name="upload_pic"]').submit(function(event) {
event.preventDefault();
const form = event.target;
const formData = new FormData(form);
$.ajax({
type: 'POST',
url: '/upload_pic',
data: formData,
processData: false,
contentType: false
}).done((data) => {
console.log(data);
})
});
});
</script>
#app.route('/upload_pic', methods=['POST'])
def upload_pic():
if 'exampleInputFile' in request.files:
file = request.files['exampleInputFile']
if file.filename != '':
# handle file here!
return jsonify(success=True)
return jsonify(success=False)

Django - template reloads after ajax response

I'm sort of new with Django and I ran through an issue. I'm sending a post request to django view and return the function back with HttpResponse in order to change my template's div contents to the passed value from my view. The issue is: once ajax responds and changes it's div's value; the page instantly reloads. Do you guys have any idea why?
Views.py
def index(request):
if request.is_ajax():
print("request is ajax")
details = request.POST.get('id')
return HttpResponse(details)
else:
return HttpResponse("Failed)
base.html
<button id="checkres">Check result</button>
<form name="testform" id="testform" method="post">
{% csrf_token %}
<input type="text" id="rowfield">
<input type="submit">
</form>
$("#testform").submit(function (event){
$row_num = $('#rowfield').val()
$("#responseresult").text('checking');
$.ajax({
type: "POST",
url: "/bot",
data: {csrfmiddlewaretoken:$('input[name=csrfmiddlewaretoken]').val(), id: $row_num},
success: function(data){
$("#responseresult").text(data);
alert(data);
}
});
});
Your javascript submit event not calling event.preventDefault(), that's the reason that after ajax response, the is refreshing. Change your javascript function to:
$("#testform").submit(function (event){
$row_num = $('#rowfield').val()
$("#responseresult").text('checking');
$.ajax({
type: "POST",
url: "/bot",
data: {csrfmiddlewaretoken:$('input[name=csrfmiddlewaretoken]').val(), id: $row_num},
success: function(data){
$("#responseresult").text(data);
alert(data);
}
});
event.preventDefault(); // prevents the page from refreshing.
});
Further read about preventDefault()
Try this for your view
def index(request):
if request.is_ajax():
print("request is ajax")
details = request.POST.get('id')
return JsonResponse(details, safe=False)
else:
return JsonResponse("Failed" safe=False)
You need to prevent submit as well.
$("#testform").submit(function (event){
$row_num = $('#rowfield').val()
$("#responseresult").text('checking');
$.ajax({
type: "POST",
url: "/bot",
data: {csrfmiddlewaretoken:$('input[name=csrfmiddlewaretoken]').val(), id: $row_num},
success: function(data){
$("#responseresult").text(data);
alert(data);
}
});
event.preventDefault(); // prevents the page from refreshing.
});

send images with ajax and django

I try to send images from <input type="file" id="file" name="file" accept="image/*" multiple> without sending al the form. I found many post which explain this so I do this
urls.py
url(r'^images/', 'app.views.images', name='images'),
view.py
def images(request):
if request.method == 'POST':
print('hello')
jquery
$("#file").change(function (){
try{
var formdata = new FormData();
var files = $('#file')[0].files;
formdata.append('file',files);
jQuery.ajax({
url: "images/",
type: "POST",
data: formdata,
processData: false,
contentType: false,
success: function (result) {
// if all is well
// play the audio file
}
});
}
catch(err){
alert(err.message);
}
});
But this gives me "POST /images/ HTTP/1.1" 403 error
I did diferent test and I think the error is the data: formdata part
You need to either send the csrf_token in the ajax request.
formdata["csrfmiddlewaretoken"] = '{{ csrf_token }}'; //add csrf token to the reauest data
jQuery.ajax({
url: "images/",
type: "POST",
data: formdata,
processData: false,
contentType: false,
success: function (result) {
// if all is well
// play the audio file
}
});
Or use #csrf_exempt on the your view.
#views.py
#csrf_exempt
def images(request):
if request.method == 'POST':
print('hello')

Django is not taking GET input in AJAX call

I am trying to take username input and return in ajax call whether the username is taken or not in Django. But the method in DJango is not taking the input. I am sharing the code here.
URL.py
url(r'^search_username/$', user.views.search_product, name="search_username"),
script + HTML
{% load staticfiles %}
{% block content %}
<form method="post">
{% csrf_token %}
<input name="search" id="search" type="text"/>
<button type="submit">Sign up</button>
</form>
{% endblock %}
$("#search").change(function () {
var username = $(this).val();
$.ajax({
url: '/search_username/',
data: {
'username': username
},
dataType: 'json',
error: function(){
alert('failure');
},
success: function (data) {
if (data.is_taken) {
alert("A user with this username already exists.");
}
}
});
});
Views.py
def search_username(request):
print('Entered into search')
username = request.GET.get('search', None)
print(username)
data = {
'is_taken': allproductlist.objects.filter(product_name_english__iexact=username).exists()
}
return JsonResponse(data)
The problem is it prints Entered into search.But when I print username it shows NOne. Can anyone please specify what is happening ?
Your Ajax is sending the data as "username" but your Python is looking for "search".
you are sending username in ajax request but you are getting search in views.py.
you can Update your ajax code:
$("#search").change(function () {
var username = $(this).val();
$.ajax({
url: '/search_username/',
data: {
'search': username
},
dataType: 'json',
error: function(){
alert('failure');
},
success: function (data) {
if (data.is_taken) {
alert("A user with this username already exists.");
}
}
});
});
2nd way is that you can change in views.py.
username = request.GET.get('username', None)

Categories

Resources