How to set number of files that can be uploaded in flask - html

I want to limit number of images per post request in flask so how can i do that
My Code
from flask import Flask, redirect, url_for, render_template, request
from werkzeug.utils import secure_filename
from flask_uploads import UploadSet , IMAGES, configure_uploads
app = Flask(__name__)
UPLOAD_FOLDER = 'static/img/'
photos = UploadSet('photos', IMAGES)
app.config['MAX_CONTENT_LENGTH'] = 4 * 1024 * 1024
app.config['UPLOADED_PHOTOS_DEST'] = UPLOAD_FOLDER
app.config['UPLOAD_FOLDER'] = UPLOAD_FOLDER
configure_uploads(app, photos)
#app.route('/upload/', methods=["POST","GET"])
def upload():
if request.method == "POST" and 'photo' in request.files:
photo = request.files['photo']
photos.save(photo)
return 'saved'
else:
return render_template("upload.html)
if __name__ == "__main__":
app.run(debug=True,host="0.0.0.0", port="5000")
I want to be able to upload multiple files but limit only 2 at back-end
also is there a way to limit file upload in html?
HTML Code
<form action="#" method="POST" enctype="multipart/form-data">
<div class="custom-file">
<label for="customFile">Choose Cover Photo --Optional--</label>
<br>
<input type="file" name="photo" id="customFile">
</div>
</form>

Below is the code to handle the file limit from backend:
#app.route('/upload', methods=["POST","GET"])
def upload():
if request.method == "POST" and 'photo' in request.files:
uploaded_photos = request.files.getlist('photo')
if len(uploaded_photos) > 2:
error = "You are only allowed to upload a maximum of 2 files"
return render_template("upload.html", error=error)
else:
for photo in uploaded_photos:
photos.save(photo)
return 'saved'
else:
return render_template("upload.html")
Need to specify multiple attribute in the input field of the file to allow multiple images to be uploaded at a time
{% if error %}
<p class=error><strong>Error:</strong> {{ error }}</p>
{% endif %}
<form action="upload" method="POST" enctype="multipart/form-data">
<div class="custom-file">
<label for="customFile">Choose Cover Photo --Optional--</label>
<br>
<input type="file" name="photo" id="customFile" multiple>
<input type = "submit" value = "submit">
</div>
</form>
You can handle it in frontend using jquery. Below is the code.
$(function(){
$("input[type = 'submit']").click(function(){
var $fileUpload = $("input[type='file']");
if (parseInt($fileUpload.get(0).files.length) > 2){
alert("You are only allowed to upload a maximum of 2 files");
}
});
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<form action="#" method="POST" enctype="multipart/form-data">
<div class="custom-file">
<label for="customFile">Choose Cover Photo --Optional--</label>
<br>
<input type="file" name="photo" id="customFile" multiple>
<input type = "submit" value = "submit">
</div>
</form>

Related

How to pass data from html to django view to use in URL?

I'm getting an error while working with django urls. I want to pass the value of Name input field after i hit the submit button.
Let's say I've this html form-
<form method='POST' action="{% url 'submittedform' slug=[firstname] %}">
{% csrf_token %}
<div>
<label for="name">Name</label>
<input type="text" name="firstname" id="name">
</div>
<div>
<label for="email">Email</label>
<input type="email" name="useremail" id="email">
</div>
<div>
<label for=phone>Phone</label>
<input type="text" name="phonenumber" id="phone" maxlength="12" pattern="[0-9]{10}">
</div>
<input type="submit" name="" id="btn" value="Submit">
</form>
Here's my view that handling it-
def submittedform(request, slug):
if request.method == 'POST':
# do something here
return render(request,'myapp/welcome.html')
return render(request,'myapp/welcome.html')
and here's my view that's handling it-
urlpatterns = [
path('index/',views.index ,name='index'),
path('welcome/<slug:slug>/',views.submittedform, name='submittedform')
]
I'm not using django forms. How can i get welcome/name working.
If you want to pass a variable to an URL you need redirect with the value:
from django.shortcuts import redirect
return redirect("/welcome/%s/" % slug)
Change the following line
<!-- Removed the bracket -->
<form method='POST' action="{% url 'submittedform' slug=firstname %}">
<!-- Children tags here -->
</form>
Now the variables are accessible in view like
def submittedform(request, slug):
if request.method == 'POST':
name = request.POST['name']
# and more variables as you need
# do something here
# do redirect here or give some message that their form has been
# submitted for their confirmation
return render(request,'myapp/welcome.html')
return render(request,'myapp/welcome.html')

flask multiple submit button

I am using flask and jinja2 to create a simple web app to serve up a simple sklearn algorithm for predictions.
In my html I need to get 4 variables: client id, textid, textid1, textid2
It currently works when I have it all connected to one submit button. But I would like to have two submit buttons to have the client id submit at the top of the page and the textid stuff at the bottom of the page. When I try to have two submit buttons it causes the page to refresh and I not able to connect the client id to the 3 textid vars.
<div class="col">
<div class="form-group">
<label>Enter Customer ID or leave blank for random selection </label>
<form method="POST">
<input name="text", id='text', placeholder="Client ID #", value="{{ client_id|round|int }}" >
<br>
<label>Enter 3 suggestions</label>
<br>
<input name="textid", placeholder="Suggested Model ID #", value="{{ request.form['textid'] }}"/>
<input name="textid1", placeholder="Suggested Model ID #", value="{{ request.form['textid1'] }}"/>
<input name="textid2", placeholder="Suggested Model ID #", value="{{ request.form['textid2'] }}"/>
<input type="submit" >
</form>
</div>
I'm simply grabbing it in flask like this:
#app.route('/suggestion', methods=['GET', 'POST'])
def with_suggestions():
try:
client_id=request.form['text']
except:
#custom function when client id is not entered to get random one
client_id = recommender.random_client_id()
try:
model_id=request.form['textid']
model_id1=request.form['textid1']
model_id2=request.form['textid2']
#other functional code after this
How can I break up the html to get two submit buttons? Thanks!!
Now that you have updated your code, all you need to do is add hidden inputs to identify where the click was originated from. Also Remove the leading slash from your url_for like I did below
<div class="col">
<div class="form-group">
<label>Enter Customer ID or leave blank for random selection </label>
<form method="POST" action={{url_for('suggestion')}}>
<input name="text", id='text', placeholder="Client ID" >
<input type="hidden" name="btn_identifier" value="client_id_identifier" />
<input type="submit" >
</form>
<form method="POST" action={{url_for('suggestion')}}>
<input name="textid", id='text', placeholder="Textid1">
<input name="textid1", id='text', placeholder="textid2 ">
<input name="textid2", id='text', placeholder="Textid3">
<input type="hidden" name="btn_identifier" value="text_id_identifier" />
<input type="submit" value="Submit">
</form>
main.py
from flask import Flask
from flask import render_template, url_for, request, redirect
app = Flask(__name__)
#app.route('/suggestion', methods=['GET', 'POST'])
def with_suggestions():
if request.methods == 'POST':
if request.form['btn_identifier'] == 'client_id_btn':
try:
client_id=request.form['text']
except:
# I think this would go in the second elif statement
model_id=request.form['textid']
model_id1=request.form['textid1']
model_id2=request.form['textid2']
elif request.form['btn_identifer'] == 'text_id_btn':
# run some code to handle a click that was originated from the second button
return render_template('index.html')
if __name__ == '__main__':
app.run()
I made some changes to your code.
index.html
<div class="col">
<div class="form-group">
<label>Enter Customer ID or leave blank for random selection </label>
<form method="POST" action={{url_for('suggestion')}}>
<input name="text", id='text', placeholder="Client ID" >
<input type="submit" >
</form>
<form method="POST" action={{url_for('suggestion')}}>
<input name="textid", id='text', placeholder="Textid1">
<input name="textid1", id='text', placeholder="textid2 ">
<input name="textid2", id='text', placeholder="Textid3">
<input type="submit" value="Submit">
</form>
</div>
main.py
from flask import Flask
from flask import render_template, url_for, request, redirect
app = Flask(__name__)
#app.route('/suggestion', methods=['GET', 'POST'])
def suggestion():
if request.method == 'POST':
try:
client_id=request.form['text']
except:
model_id=request.form['textid']
model_id1=request.form['textid1']
model_id2=request.form['textid2']
return render_template('index.html')
if __name__ == '__main__':
app.run()
Note: Values are store in the variable, print to see
I have simplified the process of fetching the info from multiple buttons. Do note that you require the python flask framework for the "request" method.
home.html
<div class="container mt-5">
<div class="row col-4">
<form method="POST" class="form-register">
<input type="submit" name="submit_button" value="Add Email">
<input type="submit" name="submit_button" value="Clear Recipients">
</form>
</div>
</div>
run.py
if request.method == 'POST':
if request.form['submit_button'] == 'Add Email':
print("add email")
elif request.form['submit_button'] == 'Clear Recipients':
print("clear recipients")
you may refer to the link provided for more example
https://www.codegrepper.com/code-examples/python/checking+if+button+pressed+flask

How to use POST in Django

I use Django 1.11.3 and python2.7
I want write a easy message board
and here is my code
<form name='my form' action='/talkpost/' method='POST'>
{% csrf_token %}
{% for m in moods %}
<input type='radio' name='mood' value='{{ m.status }}'>{{ m.status }}
{% endfor %}
<textarea name='user_post' rows=3 cols=70></textarea><br/>
<label for='user_id'>nicknameļ¼š</label>
<input id='user_id' type='text' name='user_id'>
<label for='user_pass'>password</label>
<input id='user_pass' type='password' name='user_pass'><br/>
<input type='submit' value='submit'>
<input type='reset' value='reset'>
<input type="hidden" name="ok" value="yes">
</form>
urls.py
url(r'^talkpost/', talkpost),
url(r'^talk/', talk),
talk is just for user to see the from and talkpost is for Django to get the post
request
views.py
def talk(request):
template = get_template('talk.html')
moods = Mood.objects.all()
message = 'Leave some message!'
html = template.render(locals())
return HttpResponse(html)
def talkpost(request):
template = get_template('talk.html')
if 'ok' in request.POST:
user_id = request.POST['user_id']
user_pass = request.POST['user_pass']
user_post = request.POST['user_post']
user_mood = request.POST['mood']
message = 'success!'
request_context = RequestContext(request)
request_context.push(locals())
html = template.render(request_context)
return HttpResponse(html)
I try using {% csrf_token %} and RequestContext But i still get CSRF token missing or incorrect.
I have no idea how to fix it
add the following:
from django.views.decorators.csrf import csrf_protect
your function will be:
#csrf_protect
def talkpost(request):
template = get_template('talk.html')
if 'ok' in request.POST:
user_id = request.POST['user_id']
user_pass = request.POST['user_pass']
user_post = request.POST['user_post']
user_mood = request.POST['mood']
message = 'success!'
request_context = RequestContext(request)
request_context.push(locals())
html = template.render(request_context)
return HttpResponse(html)
more info here:
https://docs.djangoproject.com/ko/1.11/ref/csrf/#how-to-use-it

How to upload an image from client side form to Google cloud storage bucket?

There is a form that uploads an image. Now I want to store it in Google cloud storage and get back to print on page. The form is : -
<form action="http://master-engine-799.appspot.com/uploadimage" method="POST" enctype="multipart/form-data">
Upload File: <input type="file" name="file"><br>
<input type="submit" name="submit" value="Submit">
</form>
and the .py file is
import webapp2
import logging
from google.appengine.ext import blobstore
from google.appengine.ext.webapp import blobstore_handlers
class UploadImageHandler(webapp2.RequestHandler):
def post(self):
# code that will upload the image to my bucket on cloud storage
upload_url = blobstore.create_upload_url('/upload',gs_bucket_name='userimagebucket')
class UploadImageHandler(webapp2.RequestHandler):
# code to show uploaded image in bucket
app = webapp2.WSGIApplication([('/uploadimage', UploadImageHandler)],
debug=True)
The upload_url provided by create_upload_url is the URL you want to use as the "action" on the form itself, rather than /uploadimage. So your HTML form should look more like:
<form action="CONTENTS_OF_UPLOAD_URL_HERE" method="POST" enctype="multipart/form-data">
<input type="file" name="file"><br>
<input type="submit" name="submit" value="Submit">
</form>
Your upload handler can then redirect the user to the page showing the results. Example:
class UploadHandler(blobstore_handlers.BlobstoreUploadHandler):
def post(self):
upload_files = self.get_uploads('file') # 'file' is file upload field in the form
blob_info = upload_files[0]
self.redirect('/serve/%s' % blob_info.key())
from __future__ import with_statement
import cloudstorage as gcs
import webapp2
import logging
from google.appengine.ext import blobstore
from google.appengine.ext.webapp import blobstore_handlers
def CreateFile(filename,imageFile):
with gcs.open(filename, 'w', content_type = 'image/jpeg') as f:
f.write(imageFile)
f.close()
blobstore_filename = '/gs' + filename
return blobstore.create_gs_key(blobstore_filename)
class MyImageHandler(webapp2.RequestHandler):
def post(self):
bucket='yourbucketname'
imageFile = self.request.get('file')
naemofFile=self.request.get('filename1')
fileName='/yourbucketname'+'/'+naemofFile
blob_key = CreateFile(fileName,imageFile)
logging.info("Blob-Key "+blob_key)
imageUrl = 'https://%(bucket)s.storage.googleapis.com/%(file)s' % {'bucket':bucket, 'file':naemofFile}
app = webapp2.WSGIApplication([('/myimagehandler', MyImageHandler)],
debug=True)
and the form is like this
<html>
<body>
<form action="http://your-app-id.appspot.com/myimagehandler" method="POST" enctype="multipart/form-data">
<input type="file" name="file"><br>
File Name : <input type="text" name="filename1"> <input type="submit" name="submit" value="Submit"> </form>
</body>
</html>

Email sending in django code is not working

Email sending in django code is not working,
it display error "[Errno 10061] No connection could be made because the target machine actively refused it"
these are my VIEWS.PY
def send_email(request):
username = request.POST.get('username', '')
from_email = request.POST.get('from_email', '')
message = request.POST.get('message', '')
if username and message and from_email:
try:
send_mail(username, from_email, message, ['canonizadocharm#ymail.com'])
except BadHeaderError:
return HttpResponse('Invalid header found.')
return HttpResponseRedirect('/contact/thanks/')
else:
# In reality we'd use a form class
# to get proper validation errors.
return HttpResponse('Make sure all fields are entered and valid.')
these are my contact.html
<FORM METHOD="POST" ACTION="/send_email/" >
{% csrf_token %}
Name: <INPUT TYPE="text" NAME="username"><BR>
Email: <INPUT TYPE="text" NAME="from_email"><BR>
Message: <BR>
<TEXTAREA NAME="message" ROWS="10" WRAP="hard">
</TEXTAREA>
<INPUT NAME="redirect" TYPE="hidden">
<INPUT NAME="NEXT_URL" TYPE="hidden">
<BR>
<INPUT TYPE="submit" VALUE="Send">
<INPUT TYPE="reset" VALUE="Clear">
</FORM>
these are my URLS.PY
url(r'^send_email/', views.send_email),
url(r'^contact/', views.contact),
url(r'^thanks/', views.thanks),
and my SETTINGS.PY
EMAIL_HOST = 'localhost'
EMAIL_HOST_USER = ''
EMAIL_HOST_PASSWORD = ''
EMAIL_PORT = 25
EMAIL_USE_TLS = True
Your action value of form must direct to view's url, mailto:canonizadocharm#ymail.com is not a valid path on your server.
UPDATED:
For example, add a new rule to urls.py like,
url(r'^mail/', views.send_mail),
Then change action value to mail.
Have your action value point to a URL, which in turn points to one of your views. For instance, your urls.py can do this.
url(r'^email/', 'project.views.send_email')
This will route your contact form to your send_mail view.
Your form in the templates has no csrf that's why you get an error of "CSRF verification failed".
<FORM METHOD=POST ACTION="/send_email/" ENCTYPE="text/plain">{% csrf_token %}
...........
</FORM>
If you want to know what is csrf just go to this link:
https://docs.djangoproject.com/en/dev/ref/contrib/csrf/
Create email setting in your settings.py, like this for example:
settings.py
# Sending mail
EMAIL_USE_TLS = True
EMAIL_HOST='smtp.gmail.com'
EMAIL_PORT=587
EMAIL_HOST_USER='your gmail account'
EMAIL_HOST_PASSWORD='your gmail password'
views.py
from django.core.mail import send_mail
def send_email(request):
if request.method == 'POST':
username = request.POST.get('username')
message = request.POST.get('message')
from_email = request.POST.get('from_email')
send_mail(username, message, from_email, ['canonizadocharm#ymail.com',])
return HttpResponseRedirect('/contact/thanks/')
else:
return HttpResponse('Make sure all fields are entered and valid.')