How to download generated python docx file using Ajax - javascript

I need to get some data from my template and send it back to my Django function using ajax, create a docx file and download it
Django Function
def download_docx_file(request):
if request.method == 'GET':
language = request.GET['lang']
data = request.GET['data']
converter = {'data': 'This is the real data'}
document = Document()
document.add_heading(f'{language} -- {converter[data]}', 0)
response = HttpResponse(content_type='application/vnd.openxmlformats-officedocument.wordprocessingml.document')
response['Content-Disposition'] = 'attachment; filename=download.docx'
document.save(response)
return response
return HttpResponse("hello")
AJAX
$("#dwnBtn").click(function(){
$.ajax({
url : "docx/",
type:"GET",
data : { lang : 'lang', data:'data' },
success : function(data){
console.log(data)
}
})
});
I am getting sth like the below response from AJAX response:
Response console.log(data)
�ܝBp��݂�;|C�ھ�w������=O���]]�%�N�����#+�reup����������Y������̉�J����3)� O��C����F�M�P�&�����rA�#��7T.��z(%h��x�x0�0Z�-i��%q�e�M�����i�"�c��-/��j��齔/ļL瞄�0� �� >�o��[��6 멆�n��s�$�
�#>˘ '��wT�� ���3�36DK�+�̓�t6 ��r��sA:���x�<>n������'U��RLqA+���ݺ�BM��:4ĞP�}���:�}ߣP����?F)�9-�W0���2�{x��#2v8N.$V�>X=/�+�c}���ּ�\y���*�J\��
���90�T�L� 3p���*Sfj(���PWWz��O�s�9]&����iO|�9�;�5��ʘdW�cl% �%;����u���%[�5������Q]$��[L>���yXg�9��2+&,iFs�Q�����u򪠵�.�E(�>W��+��M ؟E������i|���k�k�c蟴CcG�j��4s|x �F1�}��Y��,29�0M=-O����m\L��y��^On^���\���u��a���F9:zc�Sy�-�g��fu�n�C�T:{ ��4&/ ��LM9�98� �&Pnc�!��m�r�~��)74�04��0�0������M�~"��.ikjG��M�
how can I save this binary data as a .docx file?
Thank you in advance

Related

Send data to flask using fetch

I want to send data to a flask app without using ajax or jquery(only using vanilla js). I found that fetch offers to do the same however, I'm not able to make it work.
My Code
html code
<a href="#" id="link{{i}}" onclick="getdata(this.id)">
<script>
function getdata(id){
let numberId = id.slice(-1);
var data = new FormData();
data.append( {{data.links[numberId]}} );
fetch("/recipes",
{
method: "POST",
body: data
})
.then(function(res){ return res.json(); })
.then(function(data){ alert( JSON.stringify( data ) ) })
}
</script>
My python code
elif request.method == "POST":
clickedLink = flask.request.args.get("body")
print(clickedLink)
Update:
Some errors I'm receiving.
Receiving the following error

How can I download a word document created by a django app on the same app

I have a django app the creates a word document from a template. After user input I make an ajax request to my views.py and create the document. After the document is created I want it to be downloaded from the server. The document is saved in the static/documents folder. In my template I have the following:
$.ajax({
url: '/ajax/result/',
data : { 'values': JSON.stringify(dataJson),
'general': JSON.stringify(generalData)
},
method: 'GET',
contentType: "application/json",
dataType: 'json',
success: function (data){
Download('documents/'+document.getElementById('id_file_name').value+'.docx');
alert(data);
},
error: function(data) {
alert("something went wrong");
}
});
function Download(url) {
document.getElementById('my_iframe').src = url;
};
The Download(url) function is the function that downloads the document. I can get the file name of the document since it is from user input. I am currently getting a 404 error on my console.
Thanks in advance
You need to be declare actual file path
Download('http://127.0.0.1:8000/something/something/documents/'+document.getElementById('id_file_name').value+'.docx');
If you can use this Technic to your views:
file_name = ## your file name
file_root = ## your file root
with open(file_root , 'rb') as f:
wrapper = FileWrapper(f)
mimetype = "application/force-download"
guessed_type = guess_type(file_name)[0]
if guessed_type:
mimetype = guessed_type
response = HttpResponse(wrapper, mimetype)
response['Content-Disposition'] = "attachment;filename=%s"%(download_obj.get_name)
response['X-SendFile'] = "%s"%(download_obj.get_name)
return response
Don't forget to import necessary things on the top your views.py file:
from django.shortcuts import HttpResponse
from mimetypes import guess_type
from wsgiref.util import FileWrapper
Create a new url for this views, and hit the url from ajax, you can pass dynamically file name to the view

How to handle request json data in flask

I would like to send json formatted data from my html page to a url on the click of a button, but currently the data is not getting updated to the url. I've included here a small subset of the data i'm trying to post. The GET method works fine for posting initial output to the url. The result of the ajax request is the alerted error output. How can I use POST to successfully update the output to the url?
The html:
<button type="submit" class="btn-sm btn-success btn-space" id ="commitButton" name="commitButton" value="enter">Commit</button>
Javascript:
<script>
document.getElementById('commitButton').onclick = function() {
$.ajax({
url: "/processjson",
type:'POST',
headers: {
'X-CSRF-TOKEN': '{{ csrf_token() }}'
},
"dataType": "json",
"data": {"schema": {"fields":[{"name":"index","type":"integer"},{"name":"OB_TIME","type":"datetime"},{"name":"LATITUDE","type":"number"},{"name":"LONGITUDE","type":"number"}]}, "data": [{"index":0,"OB_TIME":"2015-09-03T00:00:00.000Z","LATITUDE":21.9,"LONGITUDE":-152.0}]},
"contentType": "application/json",
success: function(result) {
alert('ok');
},
error: function(result) {
alert('error');
}
})
};
</script>
Flask:
#app.route('/processjson', methods=['GET','POST'])
#login_required
def processjson():
if request.method == 'GET':
return jsonify({'result':'Test'})
# getting the table data when the commit button is pressed
if request.method == 'POST':
# gets jsonified data and convert it to a python data structure (dictionaries)
data = request.get_json()
fields = data['schema']['fields']
tableData = data['schema']['data']
return jsonify({'result':'Success!','tableData' : tableData})
Place the json data inside the request body.
You can access the request body with request.form.get('data') to get a json string. This can be load to a dict using json.load(json_str).
request.get_json() parse form data as json, but this would work if you are submitting as form data. Looking at the JS snippet, it looks like you are not submitting it as form data (you are making an ajax call), so your data will be available in the property request.json
you can use like this : request.json

JSON POST request object showing unevaluated keys

I am trying to send an AJAX post request to Django. I have a valid JSON object, which i can print/view/stringify in browser, but when it arrives in Django, the keys are unevaluated (see Django view in 2nd code block).
JS:
/* prettify payload for back */
var makeUpdatePayload = function(fieldType, fieldArray) {
var orderInfo = fieldArray.map(function(field, idx) {
var fieldInfo = field.split('-field-')
return {
'pk': fieldInfo[1],
'order': idx
}
});
return {[fieldType]: orderInfo}
};
/* post payload */
var updateFieldOrder = function( payload ) {
console.log('in ajax')
console.log(JSON.stringify(payload)) // {"search":[{"pk":"9","order":0},{"pk":"7","order":1},{"pk":"6","order":2},{"pk":"8","order":3},{"pk":"5","order":4},{"pk":"4","order":5}]}
$.ajax({
type: "POST",
url: "update_field_order/",
dataType: "json",
data: JSON.parse( JSON.stringify(payload)),
});
};
var payload = makeUpdatePayload('search', ["search-field-9", "search-field-7", "search-field-6", "search-field-8", "search-field-5", "search-field-4"])
updateFieldOrder(payload);
in my django view:
def update_field_order(request, recipe_pk):
print('post')
print(request.POST) # <QueryDict: {'search[0][pk]': ['9'], 'search[0][order]': ['0'], 'search[1][pk]': ['7'], 'search[1][order]': ['1'], 'search[2][pk]': ['6'], 'search[2][order]': ['2'], 'search[3][pk]': ['8'], 'search[3][order]': ['3'], 'search[4][pk]': ['5'], 'search[4][order]': ['4'], 'search[5][pk]': ['4'], 'search[5][order]': ['5']}>
I've tried JSON.stringify then JSON.parse -ing the payload before sending, but this doesn't help, I still see the same formatting. With JSON.stringify(payload), I get the expected output:
`<QueryDict: {'{"search":[{"pk":"9","order":0},{"pk":"7","order":1},{"pk":"6","order":2},{"pk":"8","order":3},{"pk":"5","order":4},{"pk":"4","order":5}]}': ['']}>`
Why is this happening?
I can see that the data is not correctly evaluated on sending:
I'm not entirely sure what you mean by the keys are unevaluated, but to send the object in the POST request, you should stringify it in your ajax call:
data: JSON.stringify(payload),
and then in your view, retrieve the JSON from the request.body and load it using the json module:
import json
...
payload = json.loads(request.body.decode("utf-8"))

How to send json data from Angularjs post to Django view?

I need to send json data using a POST request from Angularjs to my Django view.
I need to get data from database using this json as json format.
I tried some examples using from net resources:
JS Code:
$http({
method: 'POST',
url: '/mycard/list',
data: $.param({test: json})
});
Python Code(Django View):
def product_list(request):
if len(request.META['QUERY_STRING']) > 0:
data = request.body
data = json.loads(data)
print data
else:
f = open('./mytest.txt','r')
data = f.read()
return HttpResponse(data, mimetype='application/json')
But it returns 403 error and sometimes it returns 500 error(INTERNAL SERVER ERROR)
Service Code
var promise = $http({
method: 'post',
url: '/mycard/list',
data:data,
contentType:'application/json; charset=UTF-8',
});
return promise;
Python rest api
#csrf_exempt
#api_view(['GET','POST'])
def product_list(request):
if request.method == 'POST':
try:
stream = StringIO(request.body)
data = JSONParser().parse(stream)
except ValueError:
return Response(json.dumps(ValueError, default=json_util.default))
return Response(json.dumps(data, default=json_util.default))
else:
return Response("failure")
your json data should be formatted by JSON.stringify() like this:
$http({
method: 'POST',
url: '/mycard/list',
data: JSON.stringify({test: json})
});
403 Forbidden maybe because of an invalid CSRF token
500 : You might be not posting the data in the format that the backend is expecting. Can you please inspect and see what is the error response it is giving.

Categories