Flask giving error 400 on file upload - python

I have the following
<form action="classify_upload" method="post" id="upload-form">
<input type="file" name="imagefile" id="imagefile"/>
<input type="submit" />
</form>
And in my flask webapp I have the following rule:
#webapp.route('/upload', methods=['POST'])
def upload():
try:
imagefile = flask.request.files['imagefile']
...
except Exception as err:
...
But I am getting a error 400: bad request, which from my googling tells me Flask can not find the file under the key 'imagefile' which is the name of the input in the html. Any ideas why it is not finding it?

Turns out I need to include the enctype in the form, so the html should be
<form action="classify_upload" method="post" id="upload-form" enctype="multipart/form-data">
<input type="file" name="imagefile" id="imagefile"/>
<input type="submit" />
</form>

Related

ValueError at /polls/add/ The view polls.views.addQuestion didn't return an HttpResponse object. It returned None instead

I am trying to pass data from html template to django addQuestion view in my polls app.I want to make an add quetion along their vote options template and
I am using django==3.2
Here my html code
<form action="{% url 'polls:add' %}" method="post">
{% csrf_token %}
<label for="your_queston">Question: </label>
<input id="question" type="text">
<br>
<label for="choices">Choice 1</label>
<input id="choice1" type="text"><br>
<label for="choices">Choice 2</label>
<input id="choice2" type="text">
<br>
<label for="choices">Choice 3</label>
<input id="choice3" type="text">
<br>
<input type="submit" value="add">
</form>
and here my addQuestion function in view.py
def addQuestion(request):
if(request.POST):
try:
if(request.POST['question']):
qtext = request.POST.get('question')
q = Question(question_text=qtext, pub_date=timezone.now())
q.save()
if(request.POST['choice1']):
q.choice_set.create(
choice_text=request.POST.get('choice1'), votes=0)
if(request.POST['choice2']):
q.choice_set.create(
choice_text=request.POST.get('choice2'), votes=0)
if(request.POST['choice3']):
q.choice_set.create(
choice_text=request.POST.get('choice3'), votes=0)
q.save()
return HttpResponseRedirect(reverse('polls:index'))
except:
pass
else:
return render(request, 'polls/addQuestion.html')
In your code you have a try-except. As mentioned in the comments, always be specific in what type of expection you want to catch.
But in your code, if an exception happens, the function returns nothing, also know as None. A better way would be:
def view(request):
if request.method == 'POST':
error = False
try:
pass # Do magic here
except YourExpectedException:
# Log the exception
error = True
if error:
return render(request, 'polls/errorPage.html'
return HttpResponseRedirect(reverse('polls:index'))
else:
return render(request, 'polls/addQuestion.html')

Django - pass value from html template to python function

I am trying to spin first Django project and I am struggling how to pass value to python function from html. Basically, I have 1 placeholder with 3 buttons next to it.
I have file.html in templates.
<form method="POST" action="">
{% csrf_token %}
<input type="text" name="name_id" placeholder="placeholder value"/>
<input type="submit" value="Value 1"/>
<input type="submit" value="Value 2"/>
<input type="submit" value="Value 3"/>
</form>
I am trying to pass placeholder value to views.py. In views.py I have 3 functions. I want to execute only one of them based on value.
Value 1 from file html triggers function 1 in views py
Value 2 from file html triggers function 2 in views py
Value 3 from file html triggers function 3 in views py
I am not sure how to handle urls.py
All files are in same app/folder
Any help is much appreciated.
You can work with a name="…" attribute on the submit <button>s:
<form method="POST" action="">
{% csrf_token %}
<input type="text" name="name_id" placeholder="placeholder value"/>
<input type="submit" name="value1"/>
<input type="submit" name="value2"/>
<input type="submit" name="value3"/>
</form>
In the view you can then check with:
def some_view(request):
if request.method == 'POST':
if 'value1' in request.POST:
# …
pass
elif 'value2' in request.POST:
# …
pass
elif 'value3' in request.POST:
# …
pass

Use flask to get an image uploaded on a html form

I am new to flask and i am using google colab to do some basic flask stuff.
I have a html-form:
<!DOCTYPE html>
<html>
<body>
<h1>The input accept attribute</h1>
<form action="#" method="post">
<label for="img">Select image:</label>
<input type="file" id="img" name="img" enctype="multipart/form-data" accept="image/*">
<input type="submit" value="submit">
</form>
</body>
</html>
Then i have FLASK code as to get the uploaded image:
#app.route("/test", methods=['POST','GET'])
def test_page():
if request.method == "POST":
image = request.files.get('img', '')
image = request.form["img"]
print("img ",image)
return "<h1> yo! </h1>"
else:
return render_template('index.html')
DEBUGGING RESULTS:
#debug
print('request.method', request.method)
print('request.args', request.args)
print('request.form', request.form)
print('request.files', request.files)
request.method POST
request.args ImmutableMultiDict([])
request.form ImmutableMultiDict([('img', 'cat.jpg')])
request.files ImmutableMultiDict([])
The problem is i want to doo some processing on the uploaded image but request.files return nothing and request.form just gives me the name. Please any help will be appreciated.
The enctype attribute should be defined within the form tag, not within the input element. Here, the formatting of the data is defined when the form is transmitted.
This could fix the problem.
<form method="post" enctype="multipart/form-data">
<label for="img">Select image:</label>
<input type="file" id="img" name="img" accept="image/*">
<input type="submit" value="submit">
</form>

Flask Application Showing 404 on Post

This is my first attempt at deploying a machine learning application and also my first time using flask. Essentially the user will fill out a form on an html page and the input from the form will be used as input to the machine learning model which is saved in a pickle file, model.pkl in the code below. I am running into one snag that I can't seem to break past..
Every time I submit from index.html and post to result.html I'm receiving a 404 error.
script.py:
#importing libraries
import os
import numpy as np
import flask
import pickle
from flask import Flask, render_template, request
app=Flask(__name__)
#app.route('/')
#app.route('/index')
def index():
return flask.render_template('index.html')
def ValuePredictor(to_predict_list):
to_predict = np.array(to_predict_list).reshape(1,12)
loaded_model = pickle.load(open("model.pkl","rb"))
result = loaded_model.predict(to_predict)
return result[0]
#app.route('/result',methods = ['POST'])
def result():
if request.method == 'POST':
to_predict_list = request.form.to_dict()
to_predict_list=list(to_predict_list.values())
to_predict_list = list(map(int, to_predict_list))
result = ValuePredictor(to_predict_list)
if int(result)==1:
prediction='Income more than 50K'
else:
prediction='Income less that 50K'
return render_template("result.html",prediction=prediction)
index.html:
<html>
<body>
<h3>Income Prediction Form</h3>
<div>
<form action="/result.html" method="POST">
<label for="age">Age</label>
<input type="text" id="age" name="age">
<br>
<label for="edu">Education</label>
<select id="edu" name="edu">
<option value="0">High School</option>
<option value="1">College Degree</option>
</select>
<br>
<label for="martial_stat">Marital Status</label>
<select id="martial_stat" name="martial_stat">
<option value="0">not married</option>
<option value="1">married</option>
</select>
<br>
<label for="gender">Gender</label>
<select id="gender" name="gender">
<option value="0">Female</option>
<option value="1">Male</option>
</select>
<br>
<input type="submit" value="Submit">
</form>
</div>
</body>
</html>
result.html:
<html>
<body>
<h1> {{ prediction }}</h1>
</body>
</html>
I can't seem to figure this out. My code never seems to reach the first line in the result() function. As soon as I submit from index.html http://127.0.0.1:5000/result.html throws a 404 error. Any suggestions?
The error is very simple here, the action property in index.html should just be
<form action="/result" method="POST">
instead of
<form action="/result.html" method="POST">
You want to use /result to go through your flask function. Hope this helps!
You are posting to the endpoint /result.html:
<form action="/result.html" method="POST">
... but your route in flask is defined as /result (with no .html):
#app.route('/result',methods = ['POST'])
def result():
...
These two need to match, so consider changing the route to result.html.
Instead of <form action="/result.html" method="POST">
Can Use <form action="{{ url_for('result') }}" method="POST">

Django upload file using get method

I would like to upload a single file or files at a time using get method.
I have already done with the post method and working fine. But for some reason i would like to do the file upload using get method using command line.
The below code is which i have already tried to get the string from get method and i can able to get the varValue as string. But i would like to get the file using get method.
def home(request):
if request.method == 'GET':
varValue = request.GET.get('myfile', '')
print(varValue)`
HTML code:
<form method="GET" enctype="multipart/form-data">
<input type="file" name="myfile" accept="image/*" multiple>
<button type="submit">Upload files</button>
Try This Method
for filename, file in request.FILES.iteritems():
name = request.FILES[filename].name
A dictionary-like object containing all uploaded files. Each key in FILES is the name from the . Each value in FILES is an UploadedFile.
<form method="GET" enctype="multipart/form-data">
{% csrf_token %}
<input type="file" name="myfile">
<button type="submit">Upload File</button>
</form>
Found the solution using the post method itself. By skipping the csrf token we can do the command line script execution method.
Python views.py code below
from django.views.decorators.csrf import csrf_exempt
#csrf_exempt
def home(request):
if request.method == 'POST':
uploaded_file = request.FILES['myfile']
fs = FileSystemStorage()
name = fs.save(uploaded_file.name, uploaded_file)
print(name)
return render(request, "home.html")
HTML code:
<body>
<form method="POST" enctype="multipart/form-data">
<input type="file" name="myfile" accept="image/*" multiple>
<button type="submit">Upload files</button>
</body>
python code for file upload using post method:
import requests
files = {'myfile': open('d:\\20190819-140341-627485.png','rb')}
y = requests.post("http://127.0.0.1:8000",files=files)

Categories

Resources