Ive made a flask script which runs fine however im trying to display some values in a table on another html page which for some reason is not happening.
i've already tried going through jinja2 documentation and a few other answers but it didn't help much.
the flask file.py
from flask import Flask,render_template,request
app = Flask(__name__)
from webscraper import keeda,display_tbl
#app.route('/', methods=['POST', 'GET'])
def scraper():
if request.method == 'POST':
url = request.form['url']
df=keeda(url)
return render_template(('completed.html',display_tbl(df)))
else:
return render_template('index.html')
if __name__ == '__main__':
app.run()
the completed.html file
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Summary of Scraped Data</title>
</head>
<body>
<h1>This is what you got! </h1>
<div>
{{ display_tbl(df) }}
</div>
</body>
</html>
here's the error: jinja2.exceptions.UndefinedError: 'display_tbl' is undefined
i wanted to display a table with values on this page.
You are expecting more than what jinja2 can do for you. Please understand jinja2 is just a way to render templates which are eventually html and javascript, nothing fancy. So, in your case you cannot pass a Python function to your jinja2 template and expect that to run fine. What you can do here is to pass the data returned by display_tbl while rendering template like this:
def scraper():
...
return render_template(('completed.html', data=display_tbl(df))) # data= is important because this is how you are going to access your data in the template
…
def display_tbl(df):
… # Here you should be returning the data you want to display - a list or dict
In the template
<html>
<head>
<meta charset="UTF-8">
<title>Summary of Scraped Data</title>
</head>
<body>
<h1>This is what you got! </h1>
<div>
{{ render_data() }}
</div>
<script>
var d = data | tojson
function render_data() {
// implement the logic to handle how your data should be rendered
}
</script>
</body>
</html>
This is just a rough idea but as you can see you need to change the way you are perceiving jinja2 templates and their interaction with Python or Flask backend.
Related
view.py
map = folium.Map(location=[df['latitude'].mean(),
df['longitude'].mean()],tiles="cartodbpositron",zoom_start=12)
map.save("map.html")
context = {'my_map': map}
return render(request, 'my_map.html', context)
my_map.html:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
{{ my_map }}
</body>
browser result:
folium.folium.Map object at 0x7f49d85662b0
im not sure how to approach getting the html/js to work on the browser after the user has submitted their input via the previous html form...
I have seemed to look everywhere and there are a lot of similar problems with solutions but I could not get any to work!
Thanks!
This response is here to increase the google coverage for others who, like me, also experienced this problem when trying to render a Folium map within a Django template.
Your Code
Please see the comments inside each code block for how to render the map as expected.
views.py
map = folium.Map(location=[df['latitude'].mean(),
df['longitude'].mean()],tiles="cartodbpositron",zoom_start=12)
map.save("map.html")
# {'my_map': map} will output the object, which is what you are seeing
# to rectify this we need to turn it into an iframe which
# the template can then render.
context = {'my_map': map} # change to {'my_map': map._repr_html_()}
return render(request, 'my_map.html', context)
Template
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
# after making the change in our views.py this will return the html but
# the template will not render it as expected because it is being escaped.
# You must declare it 'safe' before it will be rendered correctly.
{{ my_map }} # change to {{ my_map | safe }}
</body>
For more information see the Folium doc page here or this SO post.
Hope that helps.
Map objects have a render method which render its html representation.
You can try directly:
<body>
{{ my_map.render }}
</body>
Or you can use the Map.render method to implement a custom inclusion tag, that way you can pass arguments to the render method. See this for reading more about inclusion and custom tags.
# The template tag.
for django.template import Library
register = Library()
#register.inclusion_tag
def render_map(map_object, **kwargs):
return map_object.render(**kwargs)
In your template:
<body>
{% render_map my_map some_arg1=arg1 some_arg2=arg2 %}
</body>
This question already has answers here:
Python Flask Render Text from Variable like render_template
(4 answers)
Closed 3 years ago.
I can not go to about_me page from the index page.
Error :
The requested URL was not found on the server.
and got url like "http://127.0.0.1:5000/%7B%7B%20url_for('about')%20%7D%7D".
from flask import Flask, redirect, url_for
app = Flask(__name__)
#app.route('/')
def index():
return '''
<!DOCTYPE html>
<html lang="en">
<head>
<title>Title</title>
</head>
<body>
<p>welcome home</p>
about
</body>
</html>
'''
#app.route('/about')
def about_me():
return 'about me'
if __name__ == '__main__':
app.run(debug=True)
The formatting you're using to insert the url_for the about me page, namely:
about
Will only work inside of a Jinja template. Those templates get processed by the template engine before the response is returned, and during that processing the notation with the two braces {{ something }} gets recognized and interpreted differently.
Here however, you are not using this notation in a Jinja template, you are using it it in a normal string, a string that does not get processed and thus does not have anything replaced.
The correct way to achieve what you want, in this case would be to parameterize the string and pass the link through formatting. E.g:
#app.route('/')
def index():
return '''
<!DOCTYPE html>
<html lang="en">
<head>
<title>Title</title>
</head>
<body>
<p>welcome home</p>
about
</body>
</html>
'''.format(about_me=url_for('about_me'))
Hope this helps!
Am Unable to sent the temp_k variable from my views to index.html. I have made a request from weather API and trying to pass it to my html.
Please suggest how we are supposed to send the variable from views to template.
views.py
from django.template.loader import render_to_string
import requests
from django.shortcuts import render
from django.http import HttpResponse
def hello(request):
my_dict = {'insert_me': "From andu.py"}
return render(request, 'mywebapp/index.html', context=my_dict)
def temperature(request):
#zip=requests.form['zip']ss
r=requests.get('http://samples.openweathermap.org/data/2.5/weather?zip=94040,us&appid=b6907d289e10d714a6e88b30761fae22')
json_object=r.json()
my_dict1={'temp_k' :json_object['main']['temp']}
return render(request,'mywebapp/index.html', context=my_dict1)
index.html
<!DOCTYPE html>
{% load staticfiles%}
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Hey</title>
<link rel="stylesheet" href={% static "cs/style.css" %}/>
</head>
<body>
<h1>This is the Header</h1>
<img src="{% static "images/youownme.jpeg" %}" atl="Uh Oh">
<h2> Temperature:{{temp_k}}</h2>
</body>
</html>
I have tried your code and it works fine so you may want to check if you are rendering the right HTML files maybe, i've changed your code to make sure it's working and it is
my_dict1={'temp_k' :json_object['wind']['speed']}
sorry but I cant write a comment yet!
Use render like this :
return render(request,'mywebapp/index.html',{'context':my_dict})
I want to make a simple python script to be run in my server. What it's supposed to do is receive requests and return values according to requests it received.
I want to access the script with a way like http://example.com/thescript.py?first=3&second=4.
and make the script to read the first and second and to do jobs with the values.
How could I do this?
The easiest way is to use Flask:
from flask import Flask, request, render_template
app = Flask(__name__)
#app.route('/', methods=['GET', 'POST'])
def index():
first = request.args.get('first')
second = request.args.get('second')
return render_template('index.html', first=first, second=second)
if __name__ == '__main__':
app.run()
And the template:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
First: {{ first }}
<br />
Second: {{ second }}
</body>
</html>
This code will simply print the two parameters provided.
In this example:
from flask import Flask, render_template, redirect, session
app = Flask(__name__)
app.secret_key="secret"
#app.route('/')
def landing():
session['results']="<p>Test one</p>"
session['results']+="<p>Test two</p>"
results=session['results']
return render_template('index.html', results=results)
app.run(debug='True')
In my html, I have something like this:
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>Game</title>
</head>
<body>
{{ results }}
</body>
</html>
The results are an html page that does not interpret the tags. So, I get a page that looks like this:
<p>Test One</p><p>Test Two</p>
You could escape the HTML:
{{ results|safe}}
or in Python
import jinja2
results = jinja2.escape(results)
The framework is escaping the HTML in the results variable to prevent security holes. Ideally you want to keep the HTML in the template and not be passed in via the variables. The best way to achieve what you want is to iterate over the values in results variable and wrap it in p tags in the template. This can be done like this:
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>Game</title>
</head>
<body>
{% for result in results %}
<p>{{ result }}</p>
{% endfor %}
</body>
</html>
The templating language is Jinja2, and you can read about that here: http://jinja.pocoo.org/
Try this:
from flask import Markup
results = Markup(results)