how to read a file using ajax and django? - python

My Ajax code:
var upfile = $("#file-id").val().split(/[\/\\]/).pop();
$.ajax({
type: 'POST',
url: '/upload/',
data:{"upfile":upfile},
success: function(data) {
if (data['success'] === "true") {
}
},
dataType: 'json'
});
return false;
Django code:
In simple form submit action request.FILES.get('upfile') works. I can read the content of file using read() But in ajax, it is not working. even request.POST.get('upfile') gives me the filename string.
How to solve this issue?

It's normal, by default a form submitted with Ajax will not upload files. You need o have a look to some file upload jquery plugins (there's a few of them, I can not suggest one as I did not try any of these yet)

Related

Make AJAX continue working and update its status on UI even if user redirects or navigates to another page

I'm using Flask and JQuery to try to achieve this but pls feel free to suggest any other stack(React/Angular) if that's super easy.
I have the below AJAX in a poll.js file
$(document).ready(function(){
$('#poll').click(function(){
$('#poll').text("Working...")
$.ajax({
url: '/poll',
data: $('form').serialize(),
type: 'GET',
success: function(response){
console.log(response);
$('#poll').text("Poll")
},
error: function(error){
console.log(error);
$('#poll').text("Poll")
}
});
});
});
and my poll function in app.py is as below:
#app.route('/poll', methods=['GET'])
def poll():
call an api and return the json response
now on the UI if i click the poll button its text changes to working and it calls the function which eventually hits the API.
While this is happening, if click the home menu or navigate elsewhere on the page, i loose the AJAX call.
How do i make the ajax call continue working i.e. calling the api and updating the UI even if we try to redirect to another page or click anywhere else?
I suggest to load the data on initial page load and then refresh after set interval. to achieve this following should give you a kick start
<script type="application/javascript">
jQuery(document).ready(function($){
/* change this
$('#poll').click(function(){
$('#poll').text("Working...")
$.ajax({
url: '/poll',
data: $('form').serialize(),
type: 'GET',
success: function(response){
console.log(response);
$('#poll').text("Poll")
},
error: function(error){
console.log(error);
$('#poll').text("Poll")
}
});
});
*/
//to this it will start with page load and refresh $('#poll') every 5 seconds
var setInt = setInterval($(function(){
$('#poll').text("Working...")
$.ajax({
url:'path to script',
data: $('#form').serialize(), //your html must have form with id="form" for this
type: 'GET',
success: function(response){
console.log(response);
$('#poll').text("Poll")
},
}).fail(function(xhr,ajaxOptin,thrownError){
//console.error(xhr.responseText);
console.error(thrownError);
});
}), 5000);
});
</script>

404 (Not Found) in ajax post url due to file upload

jQuery("#myform").submit(function (e) {
e.preventDefault();
var formData = new FormData(this);
jQuery.ajax({
type:'POST',
url:'{% url 'editJobDesc' %}',
data: formData,
cache:false,
contentType: false,
processData: false,
success: function (data) {
alert("Done");
}
});
});
The code works perfectly fine in localhost but shows 404 url not found when hosted on server.
In django views.py:
profile = request.POST.get('profile')
jd = request.FILES.get('jd')
Django urls.py:
path('editJobDesc', views.editJobDesc, name="editJobDesc"),
I found out that error is due to the file I am trying to upload using ajax. If I try to upload other inputs it works fine.
I even tried appending file with formData but still I get the same error.

URL sent to Django using AJAX is different when printed from Django

I have a JQuery event that, when a link is clicked, an AJAX POST request is sent to a Django function. There I print the recieved url and do other stuff with it. However, when it is printed (by Django) some characters in the url are changed.
The specific url this happened with was :
https://www.catholicleague.org/05press_releases/quarter%204/051110_put_on_notice.htm
Which was printed as :
https://www.catholicleague.org/05press_releases/quarter+4/051110_put_on_notice.htm
Where %20 was changed to +
Here is the AJAX and Django code:
$("a").on("click", function(e){
e.preventDefault();
if(e.target.href){
let clicked_source = e.target.href;
let csrf_tok = parent.document.getElementById("csrf_tok").value;
$.ajax({
url: "/change_origin/",
data: JSON.stringify({"clicked_source":clicked_source}),
type: "POST",
beforeSend: function (xhr, settings) { xhr.setRequestHeader("X-CSRFToken", csrf_tok );},
success: function(response) {
console.log(response.msg)
},
error:function(error) { console.log(error); }
});
}
});
def change_origin(request):
if request.method == 'POST':
received = ast.literal_eval(request.body.decode())
print(received)
clicked_source_url = received['clicked_source']
return JsonResponse({'msg': "ok"})
Where decode is used as the JSON object is received in Python as a byte-like object. And ast is used to turn the string representation of the object to an actual object (or dict) for access.
I need either:
1) A way to just send a string from Ajax to Django
2) A better way to deal with the received object as I believe using .decode() might be the one causing this issue.
EDIT: The link is the second link in the "origin" part of this article
https://www.snopes.com/fact-check/an-unmerried-woman/

Asynchronously update page with data that are stored by middleware

I have middleware, that stores all http requests into DB.
Also I have view, that fetches data from DB and put this data into the context.
views.py
def requests(request):
http_requests = WebRequest.objects.all()
context = {
"http_requests": http_requests
}
return render(request, "requests.html", context)
How can I asynchronously update data on this page as new requests come in (so, new requests should appear on this page asynchronously)? Can I use only Django features to achieve such behavior or I need to use some javascript libraries?
It depends on how much time you want to spend on the project. As Lorenzo stated, it might make sense to create an API and have javascript-frameworks (e.g. emberjs or angularjs) handle the asynchronity. I dont think you can handle this with pure django...
If you don't have time and are in for some 'hack' you could just replace the content of your page by polling the url and replacing the whole document with the response:
$.ajax({
type: "GET",
url: "<url_to_your_requests_view>",
success: function(response){
$('body').html(response);
}
});
This is NOT clean, but should work as a quick an dirty trick...
EDIT: If you only want to exchange certain parts of your site, you can break it down to just add elements to the page:
$.ajax({
type: "GET",
url: "<url_to_your_requests_view>",
success: function(response){
var newlyAddedRows = // find your newly added rows through some jquery
newlyAddedRows.forEach(function(row){
$('#request-holder').append(row);
});
}
});
OR WITH JSON
$.ajax({
type: "GET",
url: "<url_to_your_requests_api_endpoint>",
success: function(response){
var requestRows = response.requestItems
var $requestsHolder = $('#request-holder');
$requestHolder.empty();
requestRows.forEach(function(row){
requestsHolder.append('<div class="request-row">' + <visualize your data somehow> + '</div>'); //e.g. row.timestamp if you have that in your json
});
}
});

how to open a PDF file while returning the file in AJAX request success response

I get 2 dates, start and end date, via AJAX. I process the data b/w those 2 dates, generate a report and then returns an HttpResponse. The PDF report is now saved in my main project directory. Now I get a response back in AJAX. So, now how should I process the response in the success function, sent back from the sever and open a PDF file.
Thanks.
jQuery
$(function() {
$("#report_submit").click(function(){
$.ajax({
type : "POST",
url: "/reports/",
data : { 'start_date' : $("#startDate").val() , 'end_date' : $("#endDate").val() },
success : function(result){
},
error : function(result){
}
});
});
});
Django view code
def generate_report(request):
ctx = {}
if request.is_ajax():
if request.POST.has_key('start_date'):
start_date = datetime.strptime(request.POST[ 'start_date'] , '%m/%d/%Y')
end_date = datetime.strptime(request.POST[ 'end_date'] , '%m/%d/%Y')
......
# PDF GENERATED in MAIN PROJECT DIRECTORY
with open(os.path.join(os.path.dirname(__file__),'../../../../gui','Report.pdf')) as pdf:
response = HttpResponse(pdf.read(), content_type='application/pdf')
response['Content-Disposition'] = 'inline;filename=Report.pdf'
return response # so, now when I send a response back, how should I process it in AJAX success function?
pdf.closed
return render(request, 'generate_report/reports.html', ctx)
Don't try and send it in the Ajax response. Instead, get your view to generate a unique URL for the PDF, then get the JS to redirect the browser to that URL:
view:
return HttpResponse(json.dumps({'url': my_url})
JS:
$.ajax({
type : "POST",
dataType: "json",
url: "/reports/",
data : { 'start_date' : $("#startDate").val() , 'end_date' : $("#endDate").val() },
success : function(result){
var url = result['url'];
window.location = url;
},
The simplest solution would be to call window.open(pdf_url) in "success" callback, where pdf_url is the link to your generated pdf report (which you'll need to pass to response).
This problem has been discussed in the following Question... You might need to go for the jquery plugin for file download and please do not forget to set cookie in the response.
PDF file download through XHR Request
You might need to add a javascript file for the file download and also use the folowing code to generate the request to the server.
$.fileDownload(urlll,{
successCallback: function (url)
{
//success code here
},
failCallback: function (html, url)
{
//error code here
}
});
And on the server side while adding the header etc in the response do the following in response object. i.e.
aResponse.addCookie(cookie);
I hope you can solve the issue and can help others as well.. "Dangling Pointer"

Categories

Resources