I am trying to implement dropzone in my project to upload multiple images. But apparently, when I call dropzone.create(action=''), I keep getting the error that the url is not build. Below are the implementation details I did.
This is my css code filename: template.html.j2
{% block style %}
{{ dropzone.load_css() }}
{{ dropzone.style('border: 2px dashed #0087F7; margin: 10%; min-height: 400px;') }}
{% endblock %}
This is the import of dropzone:
{% block scripts %}
<script src="{{url_for('static', filename='jsfiles/dropzone.js')}}"></script>
{% endblock %}
The Body part:
{{ dropzone.create(action=url_for('folder1.upload, id=user.id'))}}
{{ dropzone.load_js() }}
{{ dropzone.config() }}
This is my function : File name:user.py
#inspection.route('/users/<int:user__id>', methods=['GET', 'POST'])
def upload(id):
//Some Code
if form.validate_on_submit() and 'photo' in request.files:
for f in request.files.getlist('photo'):
filename = secure_filename(f.filename)
print(filename)
return render_template('folder/user_details.html.j2')
The folder structure is as below:
Folder1
user.py
Templates
template.html.j2
app.py
It would be great if someone can point out why I keep getting this error.
Cannot build url for endpoint folder1.upload
Try this:
Body part
{{ dropzone.create(action=url_for('folder1.user.upload, pk=user.id'))}}
{{ dropzone.load_js() }}
{{ dropzone.config() }}
user.py
#inspection.route('/users/<int:pk>', methods=['GET', 'POST'])
def upload(pk):
//Some Code
if form.validate_on_submit() and 'photo' in request.files:
for f in request.files.getlist('photo'):
filename = secure_filename(f.filename)
print(filename)
return render_template('folder/user_details.html.j2')
Related
I'm new with s3 and trying to upload some files but the I'm getting The system cannot find the file specified: <hashed_file_name>.jpg I understand the issue. When the file is saved at the root, everything is fine. But I don't want to save the file. I want to upload it directly after the action at the form.
def upload_to_s3(file_to_upload, s3_upload_folder):
s3 = boto3.resource('s3',
aws_access_key_id=app.config['ACCESS_KEY_ID'],
aws_secret_access_key=app.config['SECRET_ACCESS_KEY'])
s3.meta.client.upload_file(file_to_upload, app.config['BUCKET_NAME'], s3_upload_folder)
def _user_img_folder(form, file_name):
username = session['name']
vacation_name = slugify(form.test_name.data)
directory = os.path.join(username, test_name)
directory = os.path.join(UPLOAD_FOLDER, directory)
return directory + '/' + file_name
#app.route('/post', methods=['GET', 'POST'])
def test():
if _is_image():
uploaded_images = request.files.getlist('photo')
for image in uploaded_images:
processed_image_name = _hash_image_name(image) # Returns hashed filename with extension
directory = _user_img_folder(form, processed_image_name)
upload_to_s3(str(processed_image_name), str(directory))
return render_template('test.html', form=form, error=error)
Thank you for your help.
EDIT 1:
{# Heavily edited #}
{% extends '_base.html' %}
{% block content %}
<form class="logVacation" enctype=multipart/form-data role="form" method="post" action="/post">
{{ form.csrf_token }}
{{ form.vacation_name(placeholder="Name Your Vacation")}}
<br>
{{ form.location(placeholder="Where was it?") }}
<br>
{{ form.with_who(placeholder='Who was with you') }}
<br><br>
{{ form.description(placeholder="Tell us about your vacation... or not.") }}<br>
{{ form.when(class="datepicker", placeholder="when?") }}
<br><br>
{{ form.photo(multiple="multiple") }}
<br>
<button class="btn btn-sm btn-success" value="upload" type="submit">Done</button>
</form>
{% endblock %}
Found the answer:
I've changed the
s3.meta.client.upload_file(file_to_upload, app.config['BUCKET_NAME'], s3_upload_folder)
to:
s3.Object(app.config['BUCKET_NAME'], s3_upload_folder).put(Body=image)
so the trick is, you must either have the file on disk and provide filepath with file_to_upload OR provide the file itself as I demonstrated in this answer.
I have created a simple Flask WTF form
class SequenceForm(Form):
sequence = StringField('Please enter a sequence in FASTA format', validators=[Required()])
submit = SubmitField('Submit')
and I have set up a route to make it appear on a page
#main.route('/bioinformatics')
def bioinformatics():
form = SequenceForm()
return render_template('bioinformatics.html', form=form)
It all works great (so far). When I point my browser to foo/bioinformatics, I see a page with a SequenceForm rendered. However, when I hit the Submit button, I am always taken back to the root page defined by #main.route('/').
How can I make the Submit button take me somewhere else? I would like to use validate_on_submit() and do stuff with the data entered in the form.
Thanks!
/Michael Knudsen
UPDATE (Code from bioinformatics.html)
{% extends "base.html" %}
{% import "bootstrap/wtf.html" as wtf %}
{% block title %}Bioinformatics{% endblock %}
{% block page_content %}
<div class="page-header">
<h1>Hello, Bioinformatics!</h1>
</div>
{{ wtf.quick_form(form) }}
{% endblock %}
You need to specify an action in the form in your html.
<form action="/url_which_handles_form_data" method="Post">
your code
</form>
make sure to give the correct path if you are using blueprints
Edit:
From https://github.com/mbr/flask-bootstrap/blob/master/flask_bootstrap/templates/bootstrap/wtf.html I found this part.
{% macro quick_form(form,
action="",
method="post",
extra_classes=None,
role="form",
form_type="basic",
horizontal_columns=('lg', 2, 10),
enctype=None,
button_map={},
id="") %}
So you can probably call
{{ wtf.quick_form(form, action="/fancy_url") }}
or
{{ wtf.quick_form(form, action=url_for("blueprint_name.fancy_url")) }}
Depending on where the view is located.
Thanks to Tim Rijavec and Zyber. I used a combination of your suggestions to come up with the following solution.
I added GET and POST to methods for the route
#main.route('/bioinformatics', methods=['GET', 'POST'])
def bioinformatics():
form = SequenceForm()
return render_template('bioinformatics.html', form=form)
and then I wrapped the wtf.quick_form call inside tags.
<form action="{{ url_for('main.bioinformatics') }}" method="POST">
{{ wtf.quick_form(form) }}
</form>
Now everything works beautifully. Thanks!
I have a function in python that displays a list of names.
def search():
with open('business_ten.json') as f:
data=f.read()
jsondata=json.loads(data)
for row in jsondata['rows']:
#print row['text']
a=str(row['name'])
print a
return a
search()
I am trying to call this function in an HTML file using Flask
{% extends "layout.html" %}
{% block content %}
<div class="jumbo">
<h2>Welcome to the Rating app<h2>
<h3>This is the home page for the Rating app<h3>
</div>
<body>
<p>{{ search.a }}</p>
</body>
{% endblock %}
My routes file is as follows:
from flask import Flask,render_template
app = Flask(__name__)
#app.route('/')
def hello_world():
return 'Hello gugugWorld!'
#app.route('/crawl')
def crawl():
return render_template('crawl.html')
There are many ways to do this:
1 - You can register a new Jinja2 filter
2 - You can pass your function as a Jinja2 parameter (This one is easier)
For method 2:
#app.route('/crawl')
def crawl():
return render_template('crawl.html', myfunction=search)
On the template call the parameter has a function
{% extends "layout.html" %}
{% block content %}
<div class="jumbo">
<h2>Welcome to the Rating app<h2>
<h3>This is the home page for the Rating app<h3>
</div>
<body>
<p>{{ myfunction() }}</p>
</body>
{% endblock %}
I'm working with Django v1.4 (Python v.2.7.3) and I'm trying to build a proofchecking application. My proofchecker has an "Examples" page with a list of links to example proofs for the user, and these are rendered on the screen one after the other. A small sample is shown below:
These example files are saved at MEDIA_ROOT on the server, and what I want is a way to make it so that clicking the link will pass the contents of the file in a POST message to a particular view. That view already has code designed to handle the user uploading a proof file directly from their file system, so essentially what I want to do is make it so that the examples.html template (shown below) passes the same kind of information except for files already stored on the server.
The code for examples.html is:
{% load staticfiles %}
<html>
<head>
<title>Anaconda</title>
<style>
body
{
overflow-y: scroll;
}
</style>
</head>
<body>
<center>
<img src="{% static "AnacondaTitleText.png" %}" alt="Title" height="40%" width="40%"/>
<div align="left" style="width:800px;">
<h2>Anaconda Examples</h2>
<p>You can click the button beside each example on this page to load it into the proof window.
{% if examples %}
The following examples are included with Anaconda:</p>
<br>
{% for example in examples %}
<p>{{ example.exampleFile.name|cut:"./" }}: link</p>
<br>
{% endfor %}
{% else %}
There are no examples currently included with Anaconda.</p>
{% endif %}
</div>
</center>
</body>
</html>
The "a href..." part will need to be changed because currently, clicking it will bring up a "Save file" dialog which is not what I want.
In my server's views.py file, I have the following code capable of handling uploaded files:
def proof(request):
if request.method == 'POST':
defaultText = request.FILES['docfile'].read()
proofText = ProofForm(request.POST)
else:
defaultText = ""
proofText = ProofForm()
c = {}
c.update(csrf(request))
c['form'] = proofText
c['default_text'] = defaultText
return render_to_response('server/proof.html', c)
I suppose what I want is a way to do the following:
The user clicks the link next to a particular example proof
All the necessary information gets loaded into request.FILES
This gets sent to the server as a POST request to proof(request)
proof(request) treats it like a regular uploaded file and reads the file contents
My models.py file looks like this:
from django.db import models
class Example(models.Model):
exampleFile = models.FileField(upload_to='.')
I'd be happy to provide additional information if necessary.
I found a solution to this, but I suspect it's a bit hacky.
Inside examples.html I include the following:
{% for example in examples %}
<form name="example" action="/server/proof" method="post">
{% csrf_token %}
<p>{{ example.exampleFile.name|cut:"./" }}</p>
<input type="hidden" name="example" value="{{ example.exampleFile.name|cut:"./" }}">
<input type="submit" value="Select">
</form>
<br>
{% endfor %}
I associate the name of the file with a hidden input element, and then in views.py I have the following code:
def proof(request):
if request.method == 'POST':
print "DATA"
print str(request.POST)
try:
defaultText = request.FILES['docfile'].read()
except:
examplePath = request.POST.get('example')
with open(join(MEDIA_DIR, examplePath), 'r') as f:
defaultText = f.read()
proofText = ProofForm(request.POST)
else:
defaultText = ""
proofText = ProofForm()
c = {}
c.update(csrf(request))
c['form'] = proofText
c['default_text'] = defaultText
return render_to_response('server/proof.html', c)
It's patchwork, but it does what I want. Hopefully I'll have time to improve the code at some later time.
As the cookbook of webpy and jinja2, I can use webpy's form or jinja2 well independently. However when I try to combining both in a template file like below, it does not work:
Template file:
$def with(form)
{% extends 'layout.html' %}
{% block maincontents %}
<h1>User</h1>
<form method="post">
$:form.render()
</form>
{% endblock %}
Part of python code:
render = render_jinja(
'templates',
encoding='utf-8',
)
class test:
def POST(self):
pass
def GET(self):
f = user_form()
return render.test(f)
$:form.render() is the Templetor rendering instruction, taken verbatim from the docs, I presume.
I believe you should use Jinja2 syntax, something like
<form method="post">
{{ form.render() | safe }}
</form>
Disclaimer: I haven't actually tested the snippet above.