So I'm working on a project using pythong flask, and sqlalchemy.
We have a datatablefull of contracts, that have the primary id of contract_id. I figured we have 2 different options of displaying the contracts.
option 1.
We have a generic view_contract.html template that makes a post request to an app route on flask and returns json of the contract to display on the page. However, I don't like this idea as much because then you can't copy and paste certain contract links to other people, since it will be the same generic webpage url
option 2.
We have an app route in flask that's #app.route(contract/< contract_id >/view) and we query the database to show that specific contract_id. However, I only know how to display the data in python using flask.jsonify. How can I generate html in the url as well?
tldr:
How do I generate a webpage such as contract/112431/view that loads the contract of id 112431 in an html form. As of right now I can only do it using python and that doesn't allow me to generate any of the html forms or details that I'd like
here's what I have right now... How would I add html to this page so it works for each contract
#app.route('/contract/<contract_id>/profile')
def view_suitor_profile(contract_id):
cs = Contract.query.filter(Contract.contract_id == contract_id).all()
cs_list = []
for c in cs:
con = {
"con id": c.contract_id,
"lcat" : c.lcat,
"desired skills" : c.desired_skill,
"mandatory skills" : c.mandatory_skill,
"location" : c.work_location
}
c_list.append(con)
return flask.jsonify(c_list=c_list)
Option 1
Use AJAX. Its easy to implement.
Option 2
simple_contracts.py
#app.route('/simple/<contract_id>/page', methods=['GET', 'POST'])
def contracts(contract_id):
result = dbs.Contracts.select().where(dbs.Contracts.id == contract_id).first()
return render_template('contracts.html', result=result)
contracts.html
<!doctype html>
<html lang="ru">
<head>
<meta charset="UTF-8">
<title>simple contracts</title>
</head>
<body>
{% if result %}
{% for contract in result %}
{{ contract.id }} <br/>
{{ contract.name }} <br/>
{{ contract.price }} <br>
{# annotation: `contract` type object, have access in methods/attributes ex namedtuple in jinja templates
ex: in python: somelist = {'id': 12, 'name': 'contractIBM', 'price':1223 }
access: somelist['id']
in jinja: somelist.id => 12
somelist.name => contractIBM etc...
#}
{% endfor %}
{% endif %}
{#for send DATA in route use ahref args link or forms#}
Get info contract 123
</body>
</html>
This gives an example of option 2.
In your view creating the list of data, instead of returning it as a json you should render a template with the data.
return flask.render_template("template.html",
c_list=c_list)
In your html you can loop through the list and extract all the elements
<div>
{% for entry in c_list %}
<p> Contract: </p>
<p>{{ entry }}</p>
{% endfor %}
</div>
Then you can try and extract more detail from the {{ entry }} element by trying something like {{ entry.lcat }}
This allows you to create a html template which will be populated with the data that you pass along it, when calling render_template. So as long as you want the same layout, but with different data, this is one approach
Related
Can we display a map on a template using django PointField?
I have a model with one PointField and then after creating a model form, I want to display the map in my template using that form.
View
def map_view(request):
form = ShopForm()
context = {
'form' : form
}
return render(request, 'ads/map.html', context)
Template
<html>
<head>
</head>
<body>
<div>
<form method="post">
{{ form }}
<input type="submit" >
</form>
</div>
</body>
</html>
I was wondering is it possible to display the map using that or do I need to something extra.
I was also having the same question and thankfully I got the right way of doing it.
Anyone who's facing this issue can follow this link
The tutorial is divided into three parts.
REMEMBER:
When you reach to the 2nd part and everything is done and you're writing python manage.py runserver
-in your template include all these
{% load leaflet_tags %}
{% leaflet_css %}
{% leaflet_js %}
Place this within your {% block content %} {% endblock content %} otherwise you'll end up rendering nothing
Have you tried using the following part of the documentation on your form?
https://docs.djangoproject.com/en/2.2/ref/contrib/gis/forms-api/#widget-classes:
from django.contrib.gis import forms
class ShopForm(forms.Form):
point = forms.PointField(widget=
forms.OSMWidget(attrs={'map_width': 800, 'map_height': 500})
)
This question already has answers here:
Flask-WTF - validate_on_submit() is never executed
(8 answers)
Closed 4 years ago.
Here is the class I created, model of the flask mega tutorial's RegistrationForm
class eyeReaderInput(FlaskForm):
article = StringField('Article')
submit = SubmitField('Enter')
And I've implemented that class in this view:
#app.route('/eyereader', methods=['GET', 'POST'])
def eyereader():
form = eyeReaderInput()
sTuple = ()
if form.validate_on_submit():
string = wikipedia.page(form.article.data)
for chunk in textwrap.wrap(string, 15):
sTuple += (chunk,)
return render_template('eyereader.html', string = sTuple, form = form)
else:
return render_template('eyereader.html', form = form)
with this being my template of eyereader.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
{% if string %}
<p><span>
{% for s in string %}
[{{s}}]<pre class="tab"></pre>
{% endfor %}
</span></p>
{% else %}
<p>Please input an article name</p>
<form action = "" method = "post">
<p>{{ form.article.label}}<br>
{{ form.article() }}</p>
<p>{{ form.submit() }}</p>
</form>
{% endif %}
</body>
</html>
What I'm hoping to do is for the user to initially access the eyereader site using a 'GET' request (which is what happens when I look at my console), and once the user inserts the wikipedia article he wishes to read, it sends a 'POST' request with a new string parameter which will make {% is string %} true and instead show the wikipedia text.
However when I'm testing this, both 'GET' and 'POST' requests end up going to the input page. Does anyone know what I may be able to change to get this to work? Thanks.
Option #1: Use two templates to handle the conditional content, tying each template to a different form action (GET/POST).
#app.route('/eyereader')
def show_template():
return render_template("eyereader.html")
Option #2: Use JavaScript to dynamically populate content as needed.
<script type="text/javascript">
$('#my_object').on('change', function() {
var selected = $( "#my_object condition:true" ).text();
if(selected == "yes")
$(Do_Something_Here)
});
</script>
I have the following flask application that displays a dashboard with various buttons. Each button executes a python function. After the execution of such a function I want the application to return to the dashboard. In order to give the user a simple log I want to output some string on the html page. For that thought about a tag above the buttons on the dashboard that get filled with the respective value. How can I do that?
Flask:
from flask import Flask, render_template
app = Flask(__name__)
#app.route("/")
def main():
return render_template('index.html')
#app.route('/something')
def do_something():
print("Hello")
return render_template('index.html', user="Successfully executed!")
if __name__ == "__main__":
app.run()
HTML:
<!DOCTYPE html>
<html>
<head>
<head>
<meta charset="UTF-8">
</head>
<title>MP Reporting</title>
</head>
<body>
<div value=user></div>
Your button
</body>
</html>
For flask template use "{{kwarg}}" i.e. in your example
<div>{{user}}</div>
will render as
<div>Successfully executed!</div>
In addition to other answers, I suggest using Flask's built-in message flashing which is simpler, and neater instead of passing variables to render_template manually. It's simple as that:
(template)
{% with messages = get_flashed_messages() %}
{% if messages %}
{% for message in messages %}
<div>{{ message }}</div>
{% endfor %}
{% endif %}
{% endwith %}
(flask view)
from flask import flash
flash("Successfully executed!")
You can get more information from here.
You can print variables using Jinja2.
To print out the variable user in your example add
{{ user }} in the html template.
If you send a list of items to the html you can output them by using a simple for:
{% for item in items %}
{{ item }}
{% endfor %}
I have a Python function that returns 1 out of 80 possible values and based on the value returned, I need to display different blocks of text. The functionality that I'm trying to achieve looks roughly like this,
<!DOCTYPE HTML>
<html>
<body>
<div id="1"> One </div>
<div id="2"> Two </div>
<div id="3"> Three </div>
{% if id == "1" %}
display div with id "1"
{% elif id == "2" %}
display div with id "2"
{% else %}
display div with id "3"
{% endif %}
</body>
</html>
So, I want to write 80 differect 'div's somewhere in the html file and display them selectively based on the value returned by the Python function. Is this even possible to do? If not, what other alternatives do I have?
Edit - The divs are not just blocks of text. They contain html too.
One way will be to create items as a list of objects:
items = [{'id': 1, 'value': 'One'}, {'id':2, 'value': 'Two'}]
return render_template('hello.html', items=items)
And in your html template (Jinja2 is default for flask):
{% for item in items %}
{% if item.id == 1 %}
<div id="1">{{ item.value }}</div>
{% elif item.id == 2 %}
<div id="2">Second item</div>
{% endif %}
{% endfor %}
But if all the divs are in html code and you want to show, hide them, then you will need javascript for that:
Add display: none; to the div style, they all will be hidden.
Let's say your python code will return item_id as an return value, we need to show that item (using jquery plugin):
Add in script tag:
var item = '{{ item_id }}';
$('#' + item).show();
To expand upon Emin's answer, you could have a dictionary with the values returned from your function as keys and the string to display as the values. Then pass the dictionary and the result of the function.
app.py
#app.route('/')
def index():
messages = {
'1': """<div id="commonCold">
<h2>Common Cold</h3>
<h3>Symptoms</h3>
<ul>
<li>Cough</li>
<li>Sore Throat</li>
<li>Congestion</li>
</ul>
<img src="commonCold.png"></img>
</div>""",
'2': """<div id="influenza">
<h2>Influenza</h3>
<h3>Symptoms</h3>
<ul>
<li>Cough</li>
<li>Sore Throat</li>
<li>Congestion</li>
</ul>
<img src="influenza.png"></img>
</div>"""
id = your_function()
return render_template('index.html', id=id, messages=messages)
index.html
<div id={{ id }}>{{ messages[id] }} </div>
Avoid conditional logic if at all possible. If not for yourself, then for the next person who touches your code. Trust me, refactoring it is arduous. You should cut out the middle man and just return a message from your function and then simply display that.
EDIT:
Updated the answer. Note that this still is not very good. Hard-coded data like this requires code updated whenever there are changes. The correct approach would be to put all this into a database. And then pass the data to html and populate it with Jinja. In MySQL for instance:
"""SELECT `name`,
img,
symptoms
FROM diseases
WHERE id = {id}""".format(id=id)
i am using django endless pagination . its working normally that just shows the numbers at the bottom .
but, i tried to integrate twitter style into it:
http://django-endless-pagination.readthedocs.org/en/latest/twitter_pagination.html#pagination-on-scroll
I have followed exactly but didnt work .
When I looked at the js code, i have seen they have used .endless_more in js class, but the generated html file has only two classes for links :
1)endless_page_current
2)endless_page_link
but they used a.endless_more in js.
Can you tell me the correct way to implement?
Thanks
Views :
from endless_pagination.decorators import page_template
#page_template("my_index_page.html")
def myview(request,template='my_index.html', extra_context=None):
data = {}
if extra_context is not None:
data.update(extra_context)
myobj = Myobj.objects.all()
data['myobj'] = myobj
return render_to_response(template, data, context_instance=RequestContext(request))
Template :
my_index.html
<script src="http://code.jquery.com/jquery-latest.js"></script>
<script src="{{ STATIC_URL }}js/endless.js"></script>
<script src="{{ STATIC_URL }}js/endless_on_scroll.js"></script>
{% include page_template %}
my_index_page.html
{% load templatetags %}
<center>
<div>
{% load endless %}
{% paginate myobj %}
{% for obj in myobj %}
{{ obj.name }}
{% endfor %}
{% show_pages %}
</div>
<center>
Here, I seriously beleive that i need to add some classes like endless_more , which the django-endless-documentation missed.
i'm using that on my portal, and it seems fine your code, you just missed one thing
{% show_more %}
that's what actually enables the twitter-style infinite pagination
edit here:
you may want to add this too:
<script type="text/javascript" charset="utf-8">
var endless_on_scroll_margin = 20;
</script>
where "20" is the number of pixels (from the bottom of the page) that triggers the scrolling
you may want to try more than one value till you get the perfect one for your project
see here and here