flowjs to upload files POST request sends empty array - python

I'm trying to use flowjs/ng-flow to upload images but I'm not getting anything on my backend.
This is the method that is supposed to receive the images in my Flask routes.py:
#app.route('/api/file/upload/', methods = ['GET', 'POST'])
#login_required
def upload_files():
if request.method == 'GET':
print "GET"
print request.args
else:
print "POST"
print request.args
return "200"
Before finding out that I had to set testChunks:false, I was receiving only a GET request and request.args looked like this:
ImmutableMultiDict([('flowFilename', u'coldplay_butterfly.JPG'), ('flowTotalChunks', u'1'), ('flowRelativePath', u'coldplay_butterfly.JPG'), ('flowTotalSize', u'35338'), ('flowCurrentChunkSize', u'35338'), ('flowIdentifier', u'35338-coldplay_butterflyJPG'), ('flowChunkSize', u'1048576'), ('flowChunkNumber', u'1')])
As for the POST, I get this:
ImmutableMultiDict([])
I have no idea why this is happening. I could also use some help on what to do after I get the array with the files, as in how to properly save the images to a folder inside my project. The only example I found was in PHP, so if someone could clarify how to do that in Python I would really appreciate it!
Thanks!

Related

Python Control Flow (Identifying different POST methods in same app route - Flask)

I'm in Flask. I have two forms on one html page, both with post methods to the same route. I have read that it is possible to use control flow to identify which form is being posted, under the same app route. I seem to be battling with the logic here. So far I have the below:
#app.route('/page-with-2-forms, methods=['GET', 'POST'])
def function():
if request.method == "POST":
if 'form_1_element_name' in request.form:
#form1
#request args from this form and do some stuff
#form2
else:
#request args from this form and do some stuff
return render_template('page.html')
The problem here is that when attempting to post #form1 it still attempts to execute the block for #form2 (the else statement). However, when posting #form2 everything works fine. As I said I seem to be missing some logic here.
The element name tag is posted under the html tag. <form id="form_1_element_name" name="form_1_element_name" action="page-with-2-forms" method="POST">
Please note that I know the conventional practice is to use WTForms, but I do not want to use it here
Any help would be massively appreciated
Will post the solution just for future reference and people having similar issues. In the original post, the if statement references the form name, as stated in the html snippet
<form id="form_1_element_name" name="form_1_element_name" action="page-with-2-forms" method="POST">
This doesn't work. Instead, the if statement should reference an element inside the actual form. In the below, I referenced the submit button, which is ID and named to a unique name, such as "editFormSubmitButton".
#app.route('/page-with-2-forms, methods=['GET', 'POST'])
def function():
if request.method == "POST":
if 'editFormSubmitButton' in request.form:
#form1
#request args from this form and do some stuff
#form2
else:
#request args from this form and do some stuff
return render_template('page.html')
This is a great alternative to WTForms
Thanks to #go2nirvana for the bit of help

strange with use request.args?

submit an Ip to post1.py
#main.route('/post1',methods=['GET','POST'])
#login_required
def post1():
Ip=request.form['Ip']
print Ip
return redirect(url_for('.post',Ip=Ip))
then redirect to post.py
#main.route('/post', methods=['GET', 'POST'])
#login_required
def post():
#Ip=request.args['Ip']
form = RepairForm(request.form)
print request.form
if request.method == "POST":
repair = Repair(Ip=form.ip.data,Series=form.series.data,Hostname=form.hostname.data,
ManagerIp=form.managerip.data,Comp=form.comp.data,
Model=form.model.data,Location=form.location.data,Box=form.box.data,
Important=form.important.data,Faultype=form.faultype.data,
Subject=form.subject.data,Body=form.body.data,Classify=form.classify.data,
Status=form.status.data,auth_id=current_user._get_current_object().id,
Owner=current_user._get_current_object().username,)
db.session.add(repair)
db.session.commit()
flash('报修成功')
return redirect(url_for('.index'))
form.ip.data=1
print form.ip.data
form.hostname.data=1
print form.hostname.data
print request.form
form.managerip.data=1
form.comp.data=1
form.model.data=1
form.location.data=1
form.box.data=1
form.important.data=1
form.faultype.data=1
form.classify.data=1
form.status.data=1
return render_template('post.html',form=form)
all test ok,but when I uncomment Ip=request.args['Ip'],then test returns 'The browser (or proxy) sent a request that this server could not understand',
This post points out the Form sending error:
Flask raises an HTTP error when it fails to find a key in the args and form dictionaries. What Flask assumes by default is that if you are asking for a particular key and it's not there then something got left out of the request and the entire request is invalid.
You can't use request.args['Ip']because Flask use a custom dictionary implementation from werkzeug called MultiDict. It has his own get method.
use request.args.get('Ip') solved this error,but do not know the reason because request.args['Ip'] still can get the data.

How do I make a POST request to flask?

I'm new to Flask and I'm trying to find a way to invoke the elif statement in the code below, without having to manually type in the url when I run my app. In other words, I'd like to be able to provide a url in one of my templates that will make a POST request for question(title). Can anyone give me insight?
#application.route('/question/<title>', methods=['GET', 'POST'])
def question(title):
if request.method == 'GET':
question = r.get(title+':question')
return render_template('AnswerQuestion.html',
question = question)
elif request.method == 'POST':
submittedAnswer = request.form['submittedAnswer'];
answer=r.get(title+':answer')
if submittedAnswer == answer:
return render_template('Correct.html');
else:
return render_template('Incorrect.html',
answer = answer,
submittedAnswer = submittedAnswer);
Looks like in thePOST request, you are getting the contents of a form. You can try to create a form whose action="/question/some_title" and method="post". So on submit this will be handled on theelif part of your flask code.
Or you can try sending am ajax request through JavaScript or jQuery, with relevant data, method and URL.

Flask login_required + next url params

I have a protected view in my app which just accepts POST requests.
#app.route("/booking", methods=("POST", ))
#login_required
def booking():
arg1 = request.form.get("arg1")
arg2 = request.form.get("arg2")
When an unauthorized user tries to access this view, I want them to
login and then be redirected here.
Right now, my login view looks like this:
#app.route("/login", methods=("GET", "POST"))
#login_required
def login():
do_login()
return redirect(request.args.get('next') or url_for('home'))
So what ends up happening is a POST request to /booking (which is the
"next" parameter) and I get a NOT ALLOWED error.
The problem is that login() makes a GET request to booking(). I can
get around that, but I am not sure how to retrieve the original POST
form arguments from /booking? Any ideas to get round that?
I would solve this by pulling the data and putting it in the session. You can remove the #login_required decorator and check this in the function using current_user.is_authorized. See Flask Sessions and Flask Login.
Something like this might work for you, I didn't test it:
from flask import session
from flask_login import current_user
#app.route("/booking", methods=("POST", ))
def booking():
if not 'arg1' in session.keys() and not 'arg2' in session.keys():
session['arg1'] = request.form.get("arg1")
session['arg2'] = request.form.get("arg2")
# Now the data will persist in the session
if current_user.is_authorized:
# Do what you need...
else:
# Redirect to login, session will persist
Why would you only use POST in the booking view ? You are probably rendering a form which should also allow GET.
#app.route("/booking", methods=['GET','POST'])
#login_required
def booking():
# render the form. something like
form = BookingForm()
# Check if POST
if request.method == 'POST':
# process the form now and do whatever you need.
return redirect(url_for('index'))
# code below will run if not POST. You should render the template here
return render_templte('booking.html')

Django controller to require method

I read the following page:
https://docs.djangoproject.com/en/1.2/topics/http/decorators/
Basically, I have a function in a controller that only accepts POST requests. And the documentation on that page allowed me to do that. However, i'm noticing that when the user sends a GET or PUT etc, the response is literally nothing. How can I send a generic error or a 404 page or something?
It doesn't return nothing. It returns a 405 Method Not Allowed HTTP status code. This indicates to the client that the requested method is not allowed (as the name describes).
If you're dead set on returning something else, just don't use the decorator. All it does is test if the requested method is in the allowed list of methods. Just add the following to your view code and you can do whatever you want for each condition:
if request.method in ['GET', 'POST']:
// allowed
else:
// not allowed
I can't remember if it was request.method or not and I don't have Django currently installed on any machines to double-check, but something like this could work.
#require_http_methods(["GET", "POST"])
def my_view(request):
if request.method == 'GET':
# return a 404 or something
# or
if request.method != 'POST':
# return a 404 or something
But shouldn't you be getting your generic 405 - Method not allowed return page if you've only allowed POST for eg. to a certain controller ?
Try this =) Good luck!
from django.http import HttpResponseNotAllowed
def my_view(request):
if request.method != 'POST':
return HttpResponseNotAllowed(permitted_methods=('POST',))

Categories

Resources