flask- how to suppress "None" from a query - python

I'm building a fantasy baseball website in python/flask, using Bulma for the css. I'm fairly new to flask development. MySql is the backend database. The page that I'm building is to show draft results. I'm done with the exception of this little pesky problem. I've done lots of searching, but haven't found my specific answer, so asking for a little help...
The page displays a table of draft results. Each row will contain either a major league baseball player or a minor league player, but not both. In other words, one of the last 2 columns should be blank, one should have a player name with a link to his mlb/milb page. What I'm getting is this:
What I want is for the "None" values to be blank. Here is my relevant code:
app.py
#app.route('/draft_results_prior/<string:yr>/')
def draft_results_prior(yr)
try:
conn = mysql.connect()
cursor = conn.cursor(pymysql.cursors.DictCursor)
cursor.execute("SELECT dr.draft_round, dr.pick_no, (SELECT af.city FROM act_franchise as af WHERE af.team_id = dr.original_team_id) orig_team, (SELECT af2.city FROM act_franchise as af2 WHERE af2.team_id = dr.traded_team_id) trade_team, dr.mlb_id, CONCAT('http://m.mlb.com/player/',dr.mlb_id) as Link, (SELECT concat(mlbr.name_first,' ', mlbr.name_last) FROM mlb_rosters as mlbr WHERE mlbr.mlb_id = dr.mlb_id) mlb_name, dr.milb_id, CONCAT('http://www.milb.com/player/index.jsp?sid=milb&player_id=',dr.milb_id) as milb_Link, (SELECT concat(milbr.name_first,' ', milbr.name_last) FROM milb_players as milbr WHERE milbr.milb_id = dr.milb_id) milb_name, dr.intl_id FROM draft_results as dr WHERE dr.ibc_year = %s",(yr))
thisDraft = cursor.fetchall()`
return render_template('draft_results_prior.html', thisDraft=thisDraft, yr=yr)
except Exception as e:
print(e)
finally:
cursor.close()
conn.close()
return render_template('draft_results_prior.html', thisDraft=thisDraft)
In draft_results_prior.html, I have this table:
<table class="table table-bordered is-fullwidth is-striped is-hoverable">
<thead>
<tr>
<th class= "yellowones">Round #</th>
<th class= "yellowones">Pick #</th>
<th class= "yellowones">Team</th>
<th class= "yellowones">Traded To</th>
<th class= "yellowones">MLB Pick</th>
<th class= "yellowones">MiLB Pick</th>
</tr>
</thead>
{% for dr in thisDraft %}
<tbody>
<td class= "greenones has-text-left">{{dr.draft_round}}</td>
<td class= "greenones has-text-left">{{dr.pick_no}}</td>
<td class= "greenones has-text-left">{{dr.orig_team}}</td>
<td class= "greenones has-text-left">{{dr.trade_team}}</td>
<td class= "greenones has-text-left">{{dr.mlb_name}}</td>
<td class= "greenones has-text-left">{{dr.milb_name}}</td>
</tbody>
{% endfor %}
</table>
I feel like I need some sort of "if" loop around the last 2 columns to check if the value is null, but I'm unsure of the syntax. Any pointers would be really appreciated!
EDITED BASED ON kungpho's answer below:
If I do this:
<td class= "greenones has-text-left">{{dr.mlb_name}}</td>
{% if dr.milb_name %}
<td class= "greenones has-text-left">{{dr.milb_name}}</td>
{% else %}
{% endif %}
I get this:
That is exactly what I want for the MiLB Pick column. So I tried to do the same to the MLB column, but it combined both columns into one:
{% if dr.mlb_name %}
<td class= "greenones has-text-left">{{dr.mlb_name}}</td>
{% else %}
{% endif %}
{% if dr.milb_name %}
<td class= "greenones has-text-left">{{dr.milb_name}}</td>
{% else %}
{% endif %}
This is what it did:
How can I keep both columns?
EDIT #2- CORRECT answer
Here's the correct answer:
{% if dr.mlb_name %}
<td class= "greenones has-text-left">{{dr.mlb_name}}</td>
{% else %}
<td class= "greenones has-text-left"></td>
{% endif %}
{% if dr.milb_name %}
<td class= "greenones has-text-left">{{dr.milb_name}}</td>
{% else %}
<td class= "greenones has-text-left"></td>
{% endif %}
Yields:
Woohoo!

In your case, yes, it looks like a simple if should do the trick. You'll still want to render the column itself, just not the contents, so your HTML stays valid (browsers will often tolerate it if you don't, but it's still better to keep it as clean as possible).
Example:
<td class="greenones has-text-left">
{% if dr.milb_Link %}
{{ dr.milb_name }}
{% else %}
{% endif %}
</td>
If you were just displaying a value and not an HTML element, Jinja2 has a built-in default filter (true here applies it to falsey values, not just undefined variables):
{{ dr.milb_name|default(' ', true) }}

Related

If statement in table in django-templates

say we have table in template
<table class="table">
<thead>
<tr>
<th>Status</th>
</tr>
</thead>
<tbody>
{% for student in students %}
<tr>
{% if {{student.academic_status}}=="promoted" %}
<td class=text-success>promoted</td>
{% endif %}
</tr>
{% endfor %}
</tbody>
</table>
So is it possible using if statement in table in django-templates
Since you are already in a template tag, you should not use curly brackets ({{ … }}) for the variable, so:
{% if student.academic_status == "promoted" %}
…
{% endif %}
The correct way to add if statement in Django Templates
follow me !
if statement
{% if condition %}
{{here you add the key that you using in the views page exactly context}}
{% endif %}

Multiple variable to store on a column of database Flask

I'm working on an app for Transport Company and on the client page, we can add Delivery Tour and these Delivery Tours can be planned on different days and hours :
exemple :
A delivery tour is planned on Monday at 4pm and Thursday 10am.
Currently, I store this in my SQLAlchemy Delivery Tour database in JSON Format like this :
{'Monday':10,'Thursday':16}
But the thing is when I rendered the HTML file I can't success to iterate through the JSON file and have the correct day and hour associated to the correct Delivery Tour...
So I was wondering is there a more efficient way to do this ? Like maybe create a new table but I have no idea how to arrange columns.
EDIT
My HTML :
<div class="card">
<div class="card-header-spe">
<p style="text-align:left;">
Delivery Tour
<span style="float:right;">
<a class=" card-category btn btn-primary" href="{{ url_for('deliver', client_id=client.id )}}">Add New</a>
</span>
</p>
</div>
<table class="table table-striped table-hover">
<thead>
<tr>
<th scope="col">Title</th>
<th scope="col">Description</th>
<th scope="col">Schedule</th>
<th scope="col">Driver</th>
</tr>
</thead>
<tbody>
<tr>
{% for deliv in delivery %}
<th scope="row">{{ deliv.title }}</th>
<td>{{ deliv.description }}</td>
<td >{{ deliv.schedule }} </td>
{% if deliv.driver_assigned %}
{% for d in driver %}
{% if d.id == deliv.driver_assigned %}
<td>{{d.first_name}}</td>
{% endif %}
{% endfor %}
{% else %}
<td></td>
{% endif %}
</tr>
{% endfor %}
</tbody>
</table>
</div>
And here is a photo of my Delivery database :
You have the basics of it already:
{% for day, hour in eval(deliv.schedule).items() %}
You would have to do eval because unless I'm wrong, you have that column stored as a string in the table.
If it were me, I'd create a table just for the schedules and make a one-to-many relationship to your delivery_tour table: (note: drop the schedule column on your delivery_tour table)
class TourSchedule(Base):
__tablename__ = 'tour_schedules'
id = Column(Integer, primary_key=True)
tour_id = Column(Integer, ForeignKey('delivery_tour.id'))
tour = relationship('DeliveryTour', backref='schedule')
day = Column(String(16))
hour = Column(Integer)
Then you can just iterate over it like you otherwise would:
<td>
<ul style="list-style-type: none;">
{% for sched in deliv.schedule %}
<li>{{sched.day}}: {{sched.hour}}</li>
{% endfor %}
</ul>
</td>

non repeating th for each table row

is there a way to remove the repeated th for each row?
I only want it to show at the top of the table, and not repeat for each row that I import from psql. I've searched and tried several options, but none seem to work for me. I'm using Flask and SQLAlchemy to connect to a postgre table. (the table is called injection)
This is part of my code:
{% block contents %}
<h1>Injection Data</h1>
{% for inject in injection %}
<table>
<tr>
<th>Timestamp</th>
<th>Cage Identifier</th>
<th>Ear Notch Number</th>
<th>Age</th>
<th>Date of Birth</th>
<th>Strain</th>
</tr>
<tr>
<td>{{inject.Timestamp}}</td>
<td>{{inject.Cage_Identifier}}</td>
<td>{{inject.Ear_Notch_Number}}</td>
<td>{{inject.Age}}</td>
<td>{{inject.DOB}}</td>
<td>{{inject.Strain}}</td>
</tr>
</table>
{% endfor %}
{% endblock contents %}
However, the column headers th will repeat for each row of data that is imported from the postgre table.
Your <th> and <table> must not be in loop only <tr><td></td></tr> needs to be in loop,
like below.
{% block contents %}
<h1>Injection Data</h1>
<table>
<tr>
<th>Timestamp</th>
<th>Cage Identifier</th>
<th>Ear Notch Number</th>
<th>Age</th>
<th>Date of Birth</th>
<th>Strain</th>
</tr>
{% for inject in injection %}
<tr>
<td>{{inject.Timestamp}}</td>
<td>{{inject.Cage_Identifier}}</td>
<td>{{inject.Ear_Notch_Number}}</td>
<td>{{inject.Age}}</td>
<td>{{inject.DOB}}</td>
<td>{{inject.Strain}}</td>
</tr>
{% endfor %}
</table>
{% endblock contents %}

Jinja lookup key in for loop

I pass 2 groups of data from my view.py to my html file.
But only one group of data is shown in the webpage.
html:
<h3>Database: A</h3>
<table>
<tr>
<th>A</th>
<th>Counts A-1</th>
<th>Counts A-2</th>
<th>Value</th>
</tr>
{% load lookup %}
{% for i in Amatch %}
<tr>
<th> {{ Amatch|lookup:forloop.counter0 }} </th>
<td> {{ Amatchtotal|lookup:forloop.counter0 }} </td>
<td> {{ AmatchCount|lookup:forloop.counter0 }} </td>
<td> {{ Avalue|lookup:forloop.counter0 }} </td>
</tr>
{% endfor %}
</table>
<h3>Database: B</h3>
<table>
<tr>
<th>B</th>
<th>Counts B-1</th>
<th>Counts B-2</th>
<th>Value</th>
</tr>
{% load lookup %}
{% for i in Bmatch %}
<tr>
<th> {{ Bmatch|lookup:forloop.counter0 }} </th>
<td> {{ Bmatchtotal|lookup:forloop.counter0 }} </td>
<td> {{ BmatchCount|lookup:forloop.counter0 }} </td>
<td> {{ Bvalue|lookup:forloop.counter0 }} </td>
</tr>
{% endfor %}
</table>
view.py
return render(request, 'analysis/result.html', {'Amatch':Amatch, 'Amatchtotal':Amatchtotal, 'AmatchCount':AmatchCount, 'A_re':A_re, 'Avalue':Avalue, 'Bmatch':Bmatch, 'Bmatchtotal':Bmatchtotal, 'BmatchCount':BmatchCount, 'B_re':B_re, 'Bvalue':Bvalue,})
Two groups of data are supposed to be shown on the page as I expected.
However, only the data from group B is shown on the page.
I tried to switch the order of group A and group B, but still only group B is shown.
I'm pretty sure data are passed successfully by checking them in terminal.
Are there anything wrong with my code?

Passing variables to a Django template

I am new to Django and have a basic question. I created a Django template, and would like to pass external variables to it, which controls colspan tag. I tried several times, but could not deliver the variable. I appreciate any help.
Python Code:
def getdjtemplate(th_span="1"):
dj_template ="""
<table class="out_">
{# headings #}
<tr>
{% for heading in headings %}
<th colspan={{ %s }}>{{ heading }}</th>
{% endfor %}
</tr>
</table>
"""%(th_span)
return dj_template
I think I should not use this, but not sure how to fix it.
<th colspan={{ %s }}>{{ heading }}</th>
You are just returning a string. You must call the django methods to render the template:
from django.template import Context, Template
def getdjtemplate(th_span="1"):
dj_template ="""
<table class="out_">
{# headings #}
<tr>
{% for heading in headings %}
<th colspan={{ th_span }}>{{ heading }}</th>
{% endfor %}
</tr>
</table>
"""
t = Template(dj_template)
headings = ["Hello"]
c = Context({'headings':headings, 'th_span':th_span})
return t.render(c)

Categories