Multiple variable to store on a column of database Flask - python

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>

Related

Django 2.1 + Ecommerce : How to create a select Function for selecting a Product Color/Size from the client side?

i am working on an Online Shop, and i want the customers to be able to select the product size and the color from the product page like this:
so far that's what i have accomplished:
but i can't select the Color nor the Size yet
here's my HTML Code:
...
<tr>
<td class="my-prod-title">Color</td>
<td>
<ul id='color'>
{% for color in product.color.all %}
<li class="square my-2" style='background-color:{{color}};'>
</li>
{% endfor %}
</ul>
</td>
</tr>
<tr>
<td class="my-prod-title">Size</td>
<td>
<ul id='size'>
{% for size in product.size.all %}
<li class="my-2">{{size}}</li>
{% endfor %}
</ul>
</td>
</tr>
...
What do i need to make that functionality ?

flask- how to suppress "None" from a query

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) }}

Python Django tables with checkbox delete option

I am new to Django and currently trying to display a table with a checkbox which displays the list of records from the database and would have a delete button to delete multiple records using checkbox.
How to display a table with checkbox and delete button?
Appreciate your help!
Here is my code related to it:
models.py
class Customer(TimeStamp):
name = models.CharField(max_length=30, unique=True)
description = models.CharField(max_length=100,blank=True,help_text="Long-form name (optional)")
comments = models.TextField(blank=True)
class Meta:
ordering = ['-id']
def __str__(self):
return self.name
def get_absolute_url(self):
return reverse('App_CUS:customer_list')
views.py
class CustomerListView(ListView):
queryset = Customer.objects.order_by('id')
model = Customer
paginate_by = 10
context_object_name = 'customers'
template_name = 'App_CUS/customer_list.html'
customer_list.html
customer_list.html:
{% extends 'index.html' %}
{% load buttons %}
{% block content %}
<div class="pull-right">
{% if perms.App_CUS.customer_add %}
{% add_button 'App_CUS:customer_add' %}
{% delete_button 'App_CUS:customer_delete' %}
{% endif %}
</div>
<h1>{% block title %}Customers{% endblock %}</h1>
<div class="col-md-9">
<div class="table-responsive">
<table class="table table-hover table-headings table-bordered">
<thead>
<tr>
<th class="pk">
<input class="toggle" title="Toggle all" type="checkbox">
</th>
<th>ID</th>
<th>Customer Name</th>
<th>Description</th>
</tr>
</thead>
<tbody>
{% for customer in customers %}
<tr>
<th class="pk">
<input class="toggle" title="Toggle all" type="checkbox">
</th>
<td>{{ customer.pk }}</td>
<td>{{ customer.name }}</td>
<td>{{ customer.description }}</td>
</tr>
{% endfor %}
</tbody>
</table>
</div>
</div>
I would add to your existing
{% for customer in customers %}
a new td tag including something like:
<td>
<div class="checkbox">
<input type="checkbox" name="name_check_{{customer.name}}" id="id_check{{customer.name}}" value="1"
{%if customer.data == 0 %}unchecked {%else%} checked {%endif%}>
</div>
<td>
I've used customer.data to represent a value stored in your db.
You could then write some js to do something on click of each new checkbox.
<script>
$(document).ready(function() {
$("#id_check_{{customer.id}}").on("click", function(){
#do something / ajax call etc..
OR
pass these values back to the view on form post (we've named each checkbox unique to the customer), then process the deletions from there.

Django: how can I display 1 field item as a header w/ remaining field items as the value?

I have a table displayed inside a collapsible, accordion style card component that contains three Fielditems (one per<td>). Using a forloop.counter, I am trying display each obj.frequency as the collapsible-header with all of the associated obj.product and obj.price items displaying within the collapsible-body.
I recognize the current layout needs to be DRY-er by only using the object.rate_set.all loop once. I left the two obj forloops since this is the only way I can get the data within the collapsible-body section of the card, even though the data is not separated correctly.
Question:
How can I display the data associated with frequency inside a card body with the frequency obj output as the header?
In addition to my template, a screenshot of my browser is included below for clarification if needed
My Template:
<div class="card">
<div class="card-body">
<ul class="collapsible popout">
{% for obj in object.rate_set.all %}
<!-- -------------------------------------------------
displays each `frequency` obj in its own accordion card
as the header. output: 1x, 3x, 6x, 12x, 24x..
------------------------------------------------- -->
{% if forloop.counter|divisibleby:3 %}
<li>
<div class="collapsible-header“>{{ obj.frequency }}</div>
<div class ="collapsible-body">
{% endif %}
{% endfor %}
<div class="table-responsive card-text">
<table>
<thead>
<tr>
<th>Product</th>
<th>Rate</th>
</tr>
</thead>
<tbody>
<!-- -----------------------------------
displays all of the obj's in the last
accordion card (24x)
------------------------------------- -->
{% for obj in object.rate_set.all %}
<tr>
<td> {{ obj.product }} </a>
<td>${{ obj.price }}</td>
</tr>
{% endfor %}
</tbody>
</table>
</div>
</div> <!–- end of ‘collapsible-body' -->
</li>
</ul>
</div>
</div>
Based on #DisneylandSC's response- below is the updated working template:
<div class="card">
<div class="card-body">
{% regroup object.rate_set.order_by by frequency as frequency_list %}
<ul class="collapsible popout">
{% for frequency in frequency_list %}
<li>
<div class="collapsible-header">
<i class="material-icons">view_day</i>{{ frequency.grouper }} Frequency Rate
</div>
<div class="collapsible-body">
<div class="table-responsive card-text">
<table class="table highlight">
<thead>
<tr>
<th>Product</th>
<th>Price</th>
</tr>
</thead>
<tbody>
{% for item in frequency.list %}
<tr>
<td>
<a class="nav-link" href="#">
{{ item.product }}
</a>
</td>
<td>${{ item.price }}</td>
</tr>
{% endfor %}
</table>
</div>
</div>
</li>
{% endfor %}
</ul>
</div>
</div>

Create a custom URL and outputting HTML form data

For my first Flask project I wanted to create a basic Flask app using Riot Game's API for League of Legends. I've got all the processing of API working but I'm having trouble going about outputting it.
I take the input from a form on one page.
<form class="navbar-form navbar-left" action="{{ url_for('current_game_output') }}" method="POST">
<div class="form-group">
<input type="text" class="form-control" placeholder="Summoner Name" name="summoner_name">
<select class="form-control" name="region">
<option value="oce">Oceanic</option>
<option value="na">North America</option>
<option value="euw">Europe West</option>
</select>
</div>
<button type="submit" class="btn btn-default" value="Send">Submit</button>
</form>
And I am trying to output the data returned from the API onto the next page.
{% extends "header.html" %}
{% block body %}
<h3> Team 2 </h3>
<table class="table table-bordered" width="50%">
<tr>
<th width="48%">Summoner Name</th>
<th width="48%">Champion</th>
<th width="4%">Pic</th>
</tr>
{% for player in team1 %}
<tr>
<td>{{ player[0] }}</td>
<td>{{ player[1] }}</td>
<td><img width="20px" src="{{ url_for('static', filename='images/championIcons/') }}{{ player[1].replace(" ", "") }}_Square_0.png"></td>
</tr>
{% endfor %}
</table>
<h3> Team 1 </h3>
<table class="table table-bordered" width="50%">
<tr>
<th width="48%">Summoner Name</th>
<th width="48%">Champion</th>
<th width="4%">Pic</th>
</tr>
{% for player in team2 %}
<tr>
<td>{{ player[0] }}</td>
<td>{{ player[1] }}</td>
<td><img width="20px" src="{{ url_for('static', filename='images/championIcons/') }}{{ player[1].replace(" ", "") }}_Square_0.png"></td>
</tr>
{% endfor %}
</table>
{% endblock %}
I'd like the URL of the output page to be dynamic'/currentgame/region/username' but keep getting errors when trying to do so.
Relevant part of my views.py file (hidden my api key):
#app.route('/header')
def header():
return render_template("header.html")
#app.route('/current')
def current():
return render_template("current.html")
#app.route('/currentgame/<region>/<name>', methods=['POST'])
def current_game_output(region, name):
region = request.form['region']
summoner_name = request.form['summoner_name']
api = RiotAPI('APIKEYGOESHERE', region)
team1, team2 = current_game_data(summoner_name, region, api)
return render_template("output.html",team1=team1,team2=team2)
Any help/pointers on the best way to output/return the data would be appreciated.
Thanks
You should post the error as well.
In a quick looks this should be fixed:
#app.route('/currentgame/<string:region>/<string:name>', methods=['POST'])
def current_game_output(region, name):
region = request.form['region']
summoner_name = request.form['summoner_name']
api = RiotAPI('APIKEYGOESHERE', region)
team1, team2 = current_game_data(summoner_name, region, api)
return render_template("output.html",team1=team1,team2=team2)
Change route to /currentgame/<string:region>/<string:name>

Categories