I need to redirect a user after he finishes filling up a form and clicking on download, which generate a pdf template and then downloads it.
I have tried redirecting from the backend side in django as well as in client side with javascript and nothing makes it.
here is what I currently have:
USER INPUT VIEW
def New_Sales(request):
#context = {}
form = modelformset_factory(historical_recent_data, fields=('id','Id', 'Description','Date','Quantity', 'NetAmount', 'customer_name', 'invoice_number'))
if request.method == 'GET':
formset = form(queryset= historical_recent_data.objects.none())
#blank_form = formset.empty_form
elif request.method == 'POST':
formset = form(request.POST)
#invoice_hidden_form = CreateInvoiceForm(request.POST)
#blank_form = formset.empty_form
if formset.is_valid():
#request.session['sale'] = formset.cleaned_data
for check_form in formset:
check_form.save()
quantity = check_form.cleaned_data.get('Quantity')
id = check_form.cleaned_data.get('Id')
update = replenishment.objects.filter(Id = id).update(StockOnHand = F('StockOnHand') - quantity)
update2 = Item2.objects.filter(reference = id).update(stock_reel = F('stock_reel') - quantity)
request.session['sale'] = formset.cleaned_data
#if invoice_hidden_form.is_valid():
#invoice_hidden_form.save()
#print('invoice_hidden_form is saved successfully')
#request.session['invoice'] = invoice_hidden_form.cleaned_data
print(formset.cleaned_data)
return redirect('/invoice/pdf/assembly/')
PDF GENERATION + DOWNLOAD VIEW:
def generate_pdf_assembly(request):
data = request.session['sale']
invoice_number = data[0]['invoice_number']
print(data)
#total_ht = request.session['sale'].get('NetAmount')
rate_list = []
for index in range(len(data)):
rate_list.append(round(data[index]['NetAmount']/data[index]['Quantity'],1))
total_ht = []
for index in range(len(data)):
total_ht.append(data[index]['NetAmount'])
print('total_ht', total_ht)
total_ht = sum(total_ht)
my_company = MyCompany.objects.get(id = 1)
tva = MyCompany.objects.aggregate(Sum('TVA'))['TVA__sum']
tva_value = round(total_ht * tva,1)
total_ttc = total_ht + tva_value
tableau = zip(rate_list, data)
context = {'data' : data,
'my_company' : my_company,
'total_ht':total_ht,
'tva_value':tva_value,
'total_ttc':total_ttc,
'rate_list':rate_list,
'tableau':tableau,
'invoice_number':invoice_number,
}
print("context",context)
pdf = render_to_pdf('pdf/invoice_generator_assembly.html', context)
if pdf:
response = HttpResponse(pdf, content_type='application/pdf')
filename = "Melt_Invoice_{}.pdf".format(data[0]['customer_name'])
content = "inline; filename={}".format(filename)
content = "attachment; filename={}".format(filename)
response['Content-Disposition'] = content
return response
return HttpResponse("Not found")
here is the redirection code looks like in pdf/invoice_generator_assembly.html, I try redirecting as a success when the data has been acquired by AJAX
<script>
$.ajax({
method: "GET",
url: "/new_sale.html",
sucess: function(context){
alert(context);
window.location = '/dash2.html';
},
failure: function(context){
alert('got an error');
}
});
</script>
But here is what gets outputed in Chrome dev tool
the redirection never occurs, send help pleaaase
I am trying to create a CSV file in JS using my code table2csv. Then I want to send it to flask using an ajax request and return it back again to the client.
But as I try to send the file to server it returns the error that ajax can't find my file.
I used console.log to check if my file is created and it is. I am stuck and don't know what to do anymore, since I am pretty new to ajax requests so any help would be great.
This is my JS part and what I am doing currently:
//On Update click renders table to csv, activates the be_filter and reopens it in the filtered_file.html
var isClicked;
jQuery("#update").on('click', function(){
var response = confirm('Are you sure you want to UPDATE rows ?');
if(response == true){
isClicked = $('#my_id').table2csv();
$.ajax({
type:'POST',
url:"{{url_for('update_file')}}",
data: {'data': isClicked},
success: function(result){
console.log(result);
},
error: function(error){
console.log(JSON.stringify(error));
}
});event.preventDefault();
//window.location.href='/update_file';
}else{
return false;
}
});
And the flask call:
#app.route('/update_file', methods=['GET', 'POST'])
#login_required
def update_file():
'''Opens the filtered_file page but with updated file'''
clicked = None
if request.method == 'POST':
clicked = request.form['data']
file_to_filter = pd.read_csv(clicked, sep=';', engine='python', encoding='utf_8_sig')
table1 = update_csv(file_to_filter)
table2 = table1.to_html(classes='my_class" id = "my_id')
return render_template('3_filtered_file.html', data=table2)
EDIT: console.log() for the error message :
POST http://127.0.0.1:5000/update_file 500 (INTERNAL SERVER ERROR)
{"readyState":4,"responseText":"<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.01 Transitional//EN\"\n \"http://www.w3.org/TR/html4/loose.dtd\">\n<html>\n <head>\n <title>FileNotFoundError: [Errno 2] No such file or directory: '"Auftragsdatum","OrderNo","ReferenceOrder","Pos","Quantity","ArtNo","ManufactureNo","ProductName","ReferencePosition","NetPerPiece","InvoiceNo","DeliveryNoteNo","SerialNumbers","Manufacturer","CI","Type","Import_ID","State","Supplier","NetPerPieceSale","OU","Modified_Date","Added_by","Modified_by","isSupplier","isManufacturer"\\n"01.04.2019","7027856072","a","100","1","2099882","GS1900-24HP-EU0101F","ZYXEL GS1900-24HP 24P GbE L2 PoE Switch","CLINO","251,09","950347427","6054042579","S182L37002129","ZYXEL","sel","","","716","ALSO","","OU00100","11-11-2019 09:58","admin","","","BPT07939"\\n"01.04.2019","7027856072","bg","200","1","3074862","EAP225 V3","TP-LINK AC1350 WLAN Dual Band Gigabit AP","CLINO","64,56","950347427","6054042579","218B410001725","TP-LINK","sel","","","716","ALSO","","OU00100","11-11-2019 09:58","admin","","","BPT07134"\\n"01.04.2019","7027856072","cd","300","1","7003581","","Mautgebühr","nan","2,09","950347427","6054042579","","","sel","","","716","ALSO","","sel","11-11-2019 ...
EDIT 2 ** this is my code for **table2csv:
(function ($) {
const _trim_text = (text) => {
return text.trim();
};
const _quote_text = (text) => {
return '"' + text + '"';
};
function convert(tb){
let output = "";
let lines = [];
$(tb).find('thead>tr').each(function () {
let line = [];
$(this).find('th:not(th:eq(0))').each(function () {
line.push(_quote_text(_trim_text($(this).text())));
});
lines.push(line.splice(0).toString());
})
$(tb).find('tbody>tr').each(function () {
let line = [];
$(this).find('td').each(function () {
if($(this).find('select').length){
line.push(_quote_text($(this).find('option:selected').val()));
}else if($(this).find('input').length){
line.push(_quote_text($(this).find('input').val()));
}
else
line.push(_quote_text(_trim_text($(this).text())));
});
lines.push(line.splice(0).toString());
})
output = lines.join('\n');
return output;
};
$.fn.table2csv = function () {
let csv = convert(this);
//cases = $('#out').append($("<pre>").text(csv));
return csv;
};
})(jQuery);
It seems you are you some jQuery plugin to convert table data to csv. It doesn't actually create file on you disk. When you are making the ajax POST request to server you are sending the form data. On the server side you have clicked = request.form['data'] here clicked is not the file. But your pandas read_csv expects the url or buffer type. You can get around this issue with StringIO.
#app.route('/update_file', methods=['GET', 'POST'])
#login_required
def update_file():
'''Opens the filtered_file page but with updated file'''
clicked = None
if request.method == 'POST':
clicked = StringIO(request.form['data'])
file_to_filter = pd.read_csv(clicked, sep=';', engine='python', encoding='utf_8_sig')
table1 = update_csv(file_to_filter)
table2 = table1.to_html(classes='my_class" id = "my_id')
return render_template('3_filtered_file.html', data=table2)
I convert the current mxGraph the user creates into XML which is stored in the database (ajax.js). I return this in my views as a JSONResponse to my ajax request (views.py).
The data stored in the database saves, as I have checked in the Django administration page and the xml gets updated per save button.
This is all working fine, however the issue is that when I refresh the page the graph created does not stay on the page.
ajax.js
var button = mxUtils.button('Save', function()
{
//var url = "{%url'login'%}"
//var url = "{% url 'myapp:productdetail' %}";
//location.href = '/saveData/'
var encoder = new mxCodec();
var node = encoder.encode(graph.getModel());
var xml = mxUtils.getPrettyXml(node);
var csrftoken = getCookie('csrftoken');
$.ajax({
type: "POST",
url: "/saveData/",
data: { "xml": xml},
headers:{
"X-CSRFToken": csrftoken
},
success: function(data){
//console.log("data" + data[0])
//console.log(graph)
//var xmlDoc = data[0]
var xmlDoc = mxUtils.parseXml(data[0]);
//var xmlDoc = mxUtils.load("/saveData/").getXml();
//console.log("xmlDoc " + xmlDoc)
var node = xmlDoc.documentElement;
//console.log("node " + node)
var dec = new mxCodec(node.ownerDocument);
//console.log("dec " + dec)
//console.log("graph model " + graph.getModel())
dec.decode(node, graph.getModel());
}
});
views.py
def saveData(request, user):
if request.method == "POST":
#Get user profile
member = Member.objects.get(username=user)
#Get XML data once user presses save
#xmlData = request.POST['xml']
member.data = request.POST['xml']
member.save()
print(member.data)
response = JsonResponse([
member.data
], safe = False);
#return render(request, 'fastcookapp/index.html', {"xmlData": member.data})
return HttpResponse(response, content_type="application/json")
return HttpResponse('POST is not used')
models.py
class Member(User):
data = models.TextField(null=True)
def __str__(self):
return self.username
P.S I have no clue why my JS is not coming in colour, I have added the javascript tag and it's not working... sorry in advance
I had to create an Ajax GET request and decode the mxGraph as done above.
In addition to this post https://stackoverflow.com/a/17732956 I want to change the order of a list via drag'n'drop and save it afterwards in django backend.
For test purposes and comprehension I've used following fiddle:
http://jsfiddle.net/LvA2z/#&togetherjs=LvHpjIr7L0
and updated the action of the form with my own action. So, instead of script.php, I used action="{% url 'save_order' %}".
In views my function looks like:
def save_order(request):
if (request.method == 'POST'):
list = request.POST['listCSV']
print(list)
Basically I want to change the order of list elements and save it afterwards with the result that after refreshing the page the saved order is given. However I do not know, how pass vars from jquery to django site. When I change the order, I have the sorted list in 'listCSV'. How do I pass this result to django site to save it in db?
EDIT:
If //$("#listsaveform").submit(); is not commented out and I fire this function referenced with my save_order function, I got this error:
jquery-1.10.2.min.js:6 POST http://localhost:8000/overview/saveOrder/ 405 (Method Not Allowed)
EDIT:
Okay, thanks for the hint. I have never worked with ajax and therefore I'm stucking a bit.
I have my list construct:
{% if habits %}
<ul id="sortable">
{% for habit in habits|dictsort:"priority" %}
<li class="ui-state-default">{{habit.title}}</li>
{% endfor %}
</ul>
{% endif %}
and this list construct is sortable with this lines of code:
$(function() {
$( "#sortable" ).sortable();
});
How does look my form?
Here is my solution based on https://impythonist.wordpress.com/2015/06/16/django-with-ajax-a-modern-client-server-communication-practise/.
In JS
// Sort & save order of habits
$(function () {
$('.sort').sortable({
handle: 'button',
cancel: '',
update: function(event, ui) {
var result = $(this).sortable( "serialize", {key: event.target.id});
// alert(result);
var csrftoken = getCookie('csrftoken');
$.ajax({
url : "/overview/saveOrder/", // the endpoint,commonly same url
type : "POST", // http method
data : { csrfmiddlewaretoken : csrftoken,
result : result,
}, // data sent with the post request
// handle a successful response
success : function(json) {
console.log(json); // another sanity check
//On success show the data posted to server as a message
// alert('Your list '+json['result']);
},
// handle a non-successful response
error : function(xhr,errmsg,err) {
console.log("FAILURE");
console.log(xhr.status + ": " + xhr.responseText); // provide a bit more info about the error to the console
}
});
}
});
// var sorted = $( ".selector" ).sortable( "serialize", { key: "sort" } );
// console.log(sorted)
})
//For getting CSRF token
function getCookie(name) {
var cookieValue = null;
if (document.cookie && document.cookie != '') {
var cookies = document.cookie.split(';');
for (var i = 0; i < cookies.length; i++) {
var cookie = jQuery.trim(cookies[i]);
// Does this cookie string begin with the name we want?
if (cookie.substring(0, name.length + 1) == (name + '=')) {
cookieValue = decodeURIComponent(cookie.substring(name.length + 1));
break;
}
}
}
return cookieValue;
}
and on Django side
def save_habit(request):
print('save_habit')
if (request.method == 'POST'):
if request.is_ajax():
habits = Habit.objects.filter(created_by=request.user.userprofile, is_active=True)
habit_title = request.POST.get('habit_title')
habit_trigger = request.POST.get('habit_trigger')
habit_routine = request.POST.get('habit_routine')
habit_targetbehavior = request.POST.get('habit_targetbehavior')
habit_image = request.POST.get('habit_image')
print(habit_image)
image = habit_image.split('http://localhost:8000/media')
print(image[1])
# TODO: was, wenn routine noch gar nicht existiert? --> speichern
obj_routine = Existingroutine.objects.get(name=habit_routine)
obj_targetbehavior = Targetbehavior.objects.get(name=habit_targetbehavior)
for habit in habits:
habit.priority += 1;
# habit.save();
habit = Habit(created_by=request.user.userprofile, is_active=True,
title=habit_title, trigger=habit_trigger, existingroutine=obj_routine,
targetbehavior=obj_targetbehavior, image=image[1])
#habit.save()
data = {"habit_title":habit_title,
"habit_trigger":habit_trigger,
"habit_routine":habit_routine,
"habit_targetbehavior":habit_targetbehavior };
return JsonResponse(data)
return redirect('display_habits')
I want to pass arrays in the jquery $.post() request.
HTML:
<input type="checkbox" id="add-check-1e30">
<input type="checkbox" id="add-check-1230">
From the above example HTML the array should be like this = ['1e30', '1230']
jQuery for sending $.post():
$("#addbox-add").click(function(){
var ukeys = new Array();
$("input[type=checkbox]:checked").each( function() {
a = $(this).attr("id");
b = a.split('-').pop();
ukeys.push(b);
});
$(".addbox").remove();
$.post("/information/portfolio/add/", {'ukeys': ukeys }, function(data) {
for(i=0; i<data.length; i++)
{
ukey = data[i].ukey;
image = data[i].image;
service = data[i].service;
if(data[i].smallimage != "")
{
image = data[i].smallimage;
}
if (image == null)
{
$(".portfolio-preview").append('<li class="portfolio-item" id="portfolio-item-'+service+'-'+ukey+'"></li>');
}
else
{
$(".portfolio-preview").append('<li class="portfolio-item" id="portfolio-item-'+service+'-'+ukey+'"><img class="portfolio-image" src="'+image+'" width="150px" height="150px"></li>');
}
}
});
});
There is no problem with the array variable in jQuery, I don't know how to send it in the post request.
I'm supposed to get those two values 1e30 and 1230 in the server. But the values I'm getting in the server is null.
Here is the server code for fetching the values in Python/Django:
def portfolio_add(request):
ukeys = request.POST.get('ukeys', '')
.....etc.....etc......
Thanks!
You have to use:
request.POST.getlist('ukeys', '')