converting and multiply float to int in django templates - python

I am fetching some data from a stocks API and I get some values (stored in the DB as float)
as follow:
YTD Change 0.379996
daily % change 0.00854
my view is as follow:
def get_stock(request):
empty = True
localStocks = Stock.objects.all()
if len(localStocks) > 0 :
empty = False
return render (request,'get_stock.html',{'empty':empty, 'output':list(localStocks)})
and my template
<section class="section-typography container u-readable">
<table>
<thead>
<tr>
<th>Ticker</th>
<th>Name</th>
<th>Price</th>
<th>Last Time</th>
<th>% Change</th>
<th>52W High</th>
<th>52W Low</th>
<th>YTD Change</th>
</tr>
</thead>
<tbody>
{% if not empty %}
{% for list_item in output %}
<tr>
<td> {{list_item.symbol }}</td>
<td> {{ list_item.companyName }}</td>
<td> {{ list_item.latestPrice }}</td>
<td> {{ list_item.latestTime }}</td>
<td> {{ list_item.changePercent }}</td>
<td> {{ list_item.week52High }}</td>
<td> {{ list_item.week52Low}}</td>
<td> {{ list_item.ytdChange }}</td>
</tr>
{% endfor %}
{% endif %}
</tbody>
</table>
</section>
{% endblock %}
the % change for the stock YTD is not 0.379996 but 37.99% and this is what I would like to display. Similarly the daily change is not 0.00854 but 0.85% . How can I manipulate the date either on the view or template to basically multiply it and display only the first 2 decimals of the float?

You need to implement a custom template tag. In your app directory create a new module named templatetags. Inside this module there should be a blank __init__.py and a random named file like percentage.py.
Your percentage.py should contain:
#percentage.py
from django import template
register = template.Library()
#register.simple_tag(name="percentage")
def percentage(value):
return str(round(value *100,2))+'%'
In any html file you want to use this tag, you should load this tag at the start of the file with {% load percentage %}. In order to pass the required value to the templatetag, you need to use it like: {% percentage list_item.changePercent %}

The best way is to change the value in view as follow:
YTD_to_pass = ((YTD*10000)//1/100)
this will multiply the value by 100 and keep 2 digits after whole number
then simply add a % symbol in template.

Related

How to build an HTML table using a for loop in Flask?

I am trying to create a table on a webpage using python and flask. I have two lists, testing_sketches and split_reconstructions.
testing_sketches: It is a list of size 14, containing 14 image addresses.
split_reconstructions: It is a list of lists containing 14 lists of length 20. Basically, there are 20 image addresses corresponding to each of the 14 images in the previous list. This means it includes 20 image addresses for each image address in testing_sketches.
I am trying to iteratively take an image from testing_sketches and display its 20 images in split_reconstructions on its right. Something like the following:
And I have tried to implement it using the following code:
<body>
<h2 style="margin-left: 1.5%;">Iterative Reconstructions</h2>
{% for i in range(len(testing_sketches)) %}
<br>
<br>
<h3 style="margin-left: 10%;">{{ i+1 }}.</h3>
<center><table border="1">
<COLGROUP>
<COL width="100"><COL width="100">
<THEAD>
<tr>
<td><center><b>Image<b></center><img src={{ testing_sketches[i] }} alt="Sorry, No Display!" border="0"/></td>
{% for j in range(20) %}
<td><center><b>Reconstruction-{{ j }}<b></center><img src={{ split_reconstructions[i][j] }} alt="Sorry, No Display!" border="0"/></td>
{% endfor %}
</tr>
</table></center>
{% endfor %}
</body>
But this results in a blank result, no alternate display, no error, just an empty result. I have tried to check the length of the lists that I am passing on, and all of them are non-empty and have correct image addresses of the form: static/test_reconstructions/images/image_04666_img.png (an example of one of the addresses)
I pass the lists and the functions used in the app.py file as follows:
#app.route('/')
def home():
return render_template('iterative_reconst.html', testing_sketchs=testing_sketchs, split_reconstructions=split_reconstructions,
len=len, range=range)
If I understood you correctly, you want a table for each entry in the first list. This table shall have the number of columns corresponding to the entry in the respective second list, headed by the entry in the first list.
For this jinja2 provides the filter length and loop indices. Your code would look something like this.
{% for sketch in testing_sketches %}
<table>
<thead>
<th>Image</th>
{% for i in range(split_reconstructions[loop.index0] | count) %}
<th>Reconstruction-{{i+1}}</th>
{% endfor %}
</thead>
<body>
<tr>
<td>{{ sketch }}</td>
{% for addr in split_reconstructions[loop.index0] %}
<td>{{ addr }}</td>
{% endfor %}
</tr>
</tbody>
</table>
{% endfor %}

Flask - cant post to route [duplicate]

This question already has answers here:
Sending data from HTML form to a Python script in Flask
(2 answers)
Closed last year.
I'm creating a configurator app for heating systems. Essentially the idea is by putting in a few inputs - the app will spit out the part number for a system pack where a user can see a detailed bill of material (BOM).
One key element is the output where we need to show a few options. I.e. if someone needs a 200kW system, there could be 3-4 packs that are suitable (190kW -210kW might be more cost effective).
I want in the first instance to show on a route the pack options that are suitable- then the user selects the pack they want- which takes you to a route (/cart) which shows the BOM.
I have put in input variables min and max which searches a database cascades.db. This successfully shows me the table of options.
from cs50 import SQL
from flask import Flask, render_template, request, url_for, redirect
app = Flask(__name__)
db = SQL("sqlite:///cascades.db")
#app.route("/")
def index():
return render_template("index.html")
#app.route("/search", methods=["GET", "POST"])
def search():
output = request.form.get("output")
hydraulic = request.form.get("hydraulic")
layout = request.form.get("layout")
controls = request.form.get("controls")
min_output = int(output) - 15
max_output = int(output) + 15
cascades = db.execute("SELECT * FROM cascades WHERE hydraulic = ? AND layout = ? AND output BETWEEN ? and ?", hydraulic, layout, min_output, max_output)
return render_template("search.html", cascades=cascades)
#app.route("/cart", methods=["GET", "POST"])
def cart():
bom_id = request.form.get("bom_id")
bom = db.execute("SELECT * FROM bom WHERE bom_id = ?", bom_id)
return render_template("bom.html", bom = bom)
When running the app- the first bit works - i.e. it shows me a list of all the packs that meet the criteria- but when clicking the 'Choose' button Im getting stuck.
{% extends "layout.html" %}
{% block body %}
<h3> Boiler Cascade Pack Options:</h3>
<table class="table table-striped table-boardered">
<tr>
<th>Part Number</th>
<th>Description</th>
<th>Number of boilers</th>
<th>BOM</th>
</tr>
{% for cascades in cascades %}
<tr>
<td scope="cascades">{{ cascades["id"] }}</td>
<td>{{ cascades["description"] }}</td>
<td>{{ cascades["number_of_boilers"] }}</td>
<td>
<form action "/cart" method="post">
<input name="bom_id" type="hidden" value="{{ cascades["id"] }}">
<input class="btn btn-primary" type="submit" value="Choose">
</form>
</td>
</tr>
{% endfor %}
</table>
{% endblock %}
But when submitting the form- where they select the pack (which has the pack id number- as a hidden form) I get the following error:
File "/home/ubuntu/cascade2/application.py", line 26, in search
min_output = int(output) - 15 TypeError: int() argument must be a
string, a bytes-like object or a number, not 'NoneType'
It seems like the route is trying to use the same logic in the second search but at this point its redundant. The second search all I want is to show me information where the Pack id = BOM.
I've noticed the URL stays on the (/search) route with this and not going to the (/cart).
I've tried several things such as putting in a IF NOT output- redirect to Cart to try and bi pass this- which successfully loads the bill of material page but nothing comes up as I don't think its posted the id to the route.
I've also changed it to GET instead of POST, which results in the query string /search?bom_id=71723827132. Which shows its picking up the part number- but staying on the /search route where I see the error.
<h3> Boiler Cascade Pack Options:</33>
<table class="table table-striped table-boardered">
<tr>
<th>Part Number</th>
<th>Description</th>
<th>Number of boilers</th>
</tr>
{% for cascade in cascade %}
<tr>
<td scope="cascade">{{ cascades["id"] }}</td>
<td>{{ cascades["description"] }}</td>
<td>{{ cascades["number_of_boilers"] }}</td>
</tr>
{% endfor %}
</table>
<br>
<h4>Bill of material:</h4>
<br>
<table class="table table-striped table-boardered">
<tr>
<th>Product ID</th>
<th>Product Description</th>
<th>Quantity</th>
</tr>
{% for bom in bom %}
<tr>
<td scope="bom">{{ bom["part_number"] }}</td>
<td>{{ bom["product_description"] }}</td>
<td>{{ bom["quantity"] }}</td>
</tr>
{% endfor %}
</table>
Been stuck on this for a month. This to me is the last piece of the puzzle. Any help/suggestions would be great. I'm new to programming so I bet I've missed something obvious :)
Your <form action "/cart" method="post"> is missing an = after action. That means the action attribute is not properly defined, and the default for action always is the URL you're currently on. That's why it stays at /search.

Django - how to make a link in an html template open an app and pass a objects value as a parameter

Hello I have an app that displays some database information in a table. Inside of the html template I am making an edit link that I want to open another app(page viewLit) while passing a value to it's view. I have added my code below. My question is I am unsure of how to make this links url and pass the object data located inside circuit.circuitid along with it. I haven't been able to find the right way to code this yet and this is just how I thought that this should be done. If anyone has a better idea I am open to suggestions.
search_custom.html(code for link)
{% for circuit in filter.qs %}
<tr>
<td class="actions">
View
</td>
<td>{{ circuit.circuitid }}</td>
</tr>
{% endfor %}
myapp/myapp/urls.py
urlpatterns = [
path('viewLit/', include('viewLit.urls')),
]
myapp/viewLit/urls.py
urlpatterns=[
path('viewLit/circuitid.id', views.viewLit, name='viewLit'),
]
myapp/viewLit/views.py
def viewLit(request, circuitid):
#display records fields here
return HttpResponse("You are at the viewLit page!")
Have a look at the documentation:
Django documentation
myapp/viewLit/urls.py
urlpatterns=[
path('viewLit/(?P<circuit_id>\w+)', views.viewLit, name='viewLit'),
]
html- template:
search_custom.html(code for link)
{% for circuit in filter.qs %}
<tr>
<td class="actions">
View
</td>
<td>{{ circuit.circuitid }}</td>
</tr>
{% endfor %}

Django template re-rendering

So I have a django DetailView that I can easily render by getting all the data that I need from get_context_data in my class based view. But the problem is that each time to render this template I would need to choose a date in this template, get the date somehow and then re-render that same template from the date picked.
I've been googling how to make this happen, there are something I could maybe do with AJAX, but maybe there is something easier to try, because I have little to no experience with AJAX/JS stuff
class PlaceDetailView(LoginRequiredMixin, PermissionCheckMixin, PlaceViewMixin, DetailView):
template_name = "places/place_detail.html"
def get_context_data(self, **kwargs):
context = super(PlaceDetailView, self).get_context_data(**kwargs)
place = context.get("object")
contract = Contract.objects.filter(pk=place.id).first()
context["renter"] = User.objects.filter(pk=contract.renter_id).first()
now = timezone.now()
meters = MeterInstallation.objects.filter(places=place.id)
context["active_meters"] = meters.filter(active_until__gte=now)
context["old_meters"] = meters.filter(active_until__lt=now)
context["services"] = ServiceTask.objects.filter(place=place)
# Need to add more context values from more models, but the date has to be given, how?
return context
place_detail_view = PlaceDetailView.as_view()
<div class="tab-pane fade show active" id="values" role="tabpanel" aria-labelledby="values-tab">
{% if values %}
<div class="table-responsive-sm">
<table class="table small">
<thead>
<tr>
<th scope="col">#</th>
<th scope="col">Values</th>
</tr>
</thead>
<tbody>
{% for value in values %}
<tr>
<th scope="row">{{ forloop.counter }}</th>
<!-- todo add needed values (type, values from/to, diff, tariff, total_price) -->
</tr>
{% endfor %}
</tbody>
</table>
</div>
{% else %}
No values.
{% endif %}
</div>
I would like to know is there an option to re-render this template when a date is being picked? Or maybe there is a better option to make this happen?:)

Django - printing multiple passed lists from views.py

I have 4 lists with the same length and would like to pass all of them to the html page.
views.py
return render(request, 'result.html', {'listA':listA, 'listB':listB, 'listC':listC, 'listD':listD})
And here is the code when I tried with Flask.
app.py
return render_template('result.html', listA = listA, listB = listB, listC = listC, listD = listD)
Below is the code in the template file; with Flask, it prints out the table without any problems, but it doesn't seem to work with Django.
How should I fix my code?
result.html
{% for i in listA %}
<tr>
<th> {{ listA[loop.index] }} </th>
<td> {{ listB[loop.index] }} </td>
<td> {{ listC[loop.index] }} </td>
<td> {{ listD[loop.index] }} </td>
</tr>
{% endfor %}
You should use a custom templatetag for implementing lookup, because django does not provide one for you.
and then use django template engine for loop for getting forloop.counter0
First create templatetags directory with __init__.py inside your app folder. Lets assume your app is called polls folder structure will look like this:
polls/
__init__.py
models.py
templatetags/
__init__.py
lookup.py
views.py
After write lookup code which goes inside lookup.py:
from django import template
register = template.Library()
#register.filter
def lookup(d, key):
return d[key]
And finlly use it in template file:
{% load lookup %}
...
{% for i in listA %}
<tr>
<th> {{ listA|lookup:forloop.counter0 }} </th>
<td> {{ listB|lookup:forloop.counter0 }}</td>
<td> {{ listC|lookup:forloop.counter0 }}</td>
<td> {{ listD|lookup:forloop.counter0 }}</td>
</tr>
{% endfor %}
...
Ref 1 - Get list item dynamically in django templates
Ref 2 - Custom template tag example
Ref 3 - Django templatetag
Ref 4 - Django template for loop

Categories

Resources