I have tried looking around finding out how to format a number in python to this specific format. Formatting a number to a currency format was pretty easy to figure out but doing this was not.
<td>{{ "{:,.2f} NOK".format(acc['AccountBalance']) }}</td>
So I simply want to format 12345678901 to 1234.56.78901. I want to use this in my flask template website. Every number is always 11 digits, and it should be formatted as 4 digits period 2 digits period 5 digits period.
EDIT: This is being used in a Flask template, on numbers retrieved from an SQLite table and put into a list. It is the accs['ID'] that is getting this formatting done on it.
accs = db.execute(
'SELECT a.ID, ownerID, AccountBalance, AccountName'
' FROM atbl_bank_accounts a JOIN atbl_system_users u ON a.ownerID = u.ID'
' WHERE a.ownerID = ?',
(g.user['ID'],)
).fetchall()
This again is posted in to a table on the website using flask template as so:
<table class="table table-striped table-hover table-borderless mt-5">
<thead>
<tr>
<th class="col-2" scope="col">Account Number</th>
<th class="col-4" scope="col">Account Name</th>
<th class="col-4" scope="col">Amount left</th>
<th class="col-2" scope="col">Actions</th>
</tr>
</thead>
<tbody>
{% for acc in accs %}
<tr>
<th scope="row">{{ acc['ID'] }}</th>
<td>{{ acc['AccountName'] }}</td>
<!--<td>{{ acc['AccountBalance'] }}</td>-->
<td>{{ "{:,.2f} NOK".format(acc['AccountBalance']) }}</td>
<td>
<button type="button" class="btn btn-light" data-toggle="tooltip" data-placement="top" title="Edit name of account"><i class="fas fa-edit"></i></button>
<button type="button" class="btn btn-light" data-toggle="tooltip" data-placement="top" title="Transfer money from account"><i class="fas fa-file-invoice-dollar"></i></button>
<button type="button" class="btn btn-light" data-toggle="tooltip" data-placement="top" title="Delete account"><i class="fas fa-trash"></i></button>
</td>
</tr>
{% endfor %}
</tbody>
</table>
{% endblock %}
So I either need a solution that works straight in the HTML or in the python script. Apologies for not being clear enough.
I did search a fair bit around, but if I skipped an article about this I'm sorry.
Thanks for the answers in advance.
Turn the integer to a str and use slices along with join.
In [22]: p = 12345678901
In [23]: q = str(p)
In [24]: '.'.join((q[:4],q[4:-5],q[-5:]))
Out[24]: '1234.56.78901'
Or you could use slice objects which is basically the same thing but you get to name them.
In [33]: first, middle, last = slice(0,4),slice(4,-5),slice(-5,None)
In [34]: '.'.join((q[first],q[middle],q[last]))
Out[34]: '1234.56.78901'
Thanks to NoNickAvailable and wwii for the tips.
Since I was using this is with a flask template and for loop, I couldn't use wwii's answer directly. With help from this stackoverflow article, I managed to make a working version.
I retrive the data from the database as follows:
accs = db.execute(
'SELECT a.ID, ownerID, AccountBalance, AccountName'
' FROM atbl_bank_accounts a JOIN atbl_system_users u ON a.ownerID = u.ID'
' WHERE a.ownerID = ?',
(g.user['ID'],)
).fetchall()
Then I had to use dict:
IDrows = [dict(row) for row in accs]
Then to format the numbers with my very specific format I used what wwii and NoNickAvailable answered:
for i in IDrows:
i['ID'] = '.'.join((str(i['ID'])[:4],str(i['ID'])[4:-5],str(i['ID'])[-5:]))
The numbers were than all individually formatted and easily inserted into my table:
<table class="table table-striped table-hover table-borderless mt-5">
<thead>
<tr>
<th class="col-2" scope="col">Account Number</th>
<th class="col-4" scope="col">Account Name</th>
<th class="col-4" scope="col">Amount left</th>
<th class="col-2" scope="col">Actions</th>
</tr>
</thead>
<tbody>
{% for acc in IDrows %}
<tr>
<th scope="row">{{ acc['ID'] }}</th>
<td>{{ acc['AccountName'] }}</td>
<!--<td>{{ acc['AccountBalance'] }}</td>-->
<td>{{ "{:,.2f} NOK".format(acc['AccountBalance']) }}</td>
<td>
<button type="button" class="btn btn-light" data-toggle="tooltip" data-placement="top" title="Edit name of account"><i class="fas fa-edit"></i></button>
<button type="button" class="btn btn-light" data-toggle="tooltip" data-placement="top" title="Transfer money from account"><i class="fas fa-file-invoice-dollar"></i></button>
<button type="button" class="btn btn-light" data-toggle="tooltip" data-placement="top" title="Delete account"><i class="fas fa-trash"></i></button>
</td>
</tr>
{% endfor %}
</tbody>
</table>
Related
I want to have 2 separate query lists on the same page but with different filters. First list must be played and the second one paused. This is what I came up with in my views.py file but it throws an error like this: UnboundLocalError at /
local variable 'formset_paused' referenced before assignment
def home_view(request):
#campaigns in progress
queryset = Campaign.objects.filter(is_active=True, completion_percent__lt=100)
if request.method == "POST":
form_type = request.POST.get('id')
if form_type == 'campaign_status':
formset = CampaignStatusFormSet(
request.POST, request.FILES,
queryset=queryset,
)
formset.save()
else:
formset = CampaignStatusFormSet(queryset=queryset)
campaigns_and_forms = list(zip(queryset, formset))
#paused campaigns
queryset_paused = Campaign.objects.filter(is_active=False, completion_percent__lt=100)
if request.method == "POST":
form_type_paused = request.POST.get('id_paused')
if form_type_paused == 'campaign_status_paused':
formset_paused = CampaignStatusFormSet(
request.POST, request.FILES,
queryset=queryset_paused,
)
formset_paused.save()
else:
formset_paused = CampaignStatusFormSet(queryset=queryset_paused)
paused_campaigns_and_forms = list(zip(queryset_paused, formset_paused))
context = {
'formset': formset,
'formset_paused': formset_paused,
'campaigns_and_forms': campaigns_and_forms,
'paused_campaigns_and_forms': paused_campaigns_and_forms,
}
return render(request, 'campaigns_in_progress.html', context)
Here are the tables in my template where I make those 2 lists.
<table class="table table-striped table-hover table-bright table-bordered align-middle">
<thead>
<tr>
<th scope="col">ID</th>
<th scope="col">Nazwa</th>
<th scope="col">Temat</th>
<th scope="col">Nadawca</th>
<th scope="col">Procent Realizacji</th>
<th scope="col">Start Kampani</th>
<th scope="col">Stan</th>
</tr>
</thead>
<tbody>
<form method="post" id="campaign_status"> {% csrf_token %}
<input type='hidden' value='campaign_status' name='id'>
{{ formset.management_form }}
{% for campaign, form in campaigns_and_forms %}
<tr>
<td>{{ campaign.campaign_id }}</td>
<td>{{ campaign.name }}</td>
<td>{{ campaign.topic }}</td>
<td>{{ campaign.sender }}</td>
<td>
<div class="progress">
<div class="progress-bar" role="progressbar" style="width: {{campaign.completion_percent}}%;" aria-valuenow="{{campaign.completion_percent}}" aria-valuemin="0" aria-valuemax="100">{{campaign.completion_percent}}%</div>
</div>
</td>
<td>{{ campaign.start_date }}</td>
<td>{{ form.as_p }}</td>
</tr>
{% endfor %}
</form>
</tbody>
</table>
<h4>Kampanie zatrzymane</h4>
<table class="table table-striped table-hover table-bright table-bordered align-middle">
<thead>
<tr>
<th scope="col">ID</th>
<th scope="col">Nazwa</th>
<th scope="col">Temat</th>
<th scope="col">Nadawca</th>
<th scope="col">Procent Realizacji</th>
<th scope="col">Start Kampani</th>
<th scope="col">Stan</th>
</tr>
</thead>
<tbody>
<form method="post" id="campaign_status_paused"> {% csrf_token %}
<input type='hidden' value='campaign_status_paused' name='id_paused'>
{{ formset_paused.management_form }}
{% for campaign, form in paused_campaigns_and_forms %}
<tr>
<td>{{ campaign.campaign_id }}</td>
<td>{{ campaign.name }}</td>
<td>{{ campaign.topic }}</td>
<td>{{ campaign.sender }}</td>
<td>
<div class="progress">
<div class="progress-bar" role="progressbar" style="width: {{campaign.completion_percent}}%;" aria-valuenow="{{campaign.completion_percent}}" aria-valuemin="0" aria-valuemax="100">{{campaign.completion_percent}}%</div>
</div>
</td>
<td>{{ campaign.start_date }}</td>
<td>{{ form.as_p }}</td>
</tr>
{% endfor %}
</form>
</tbody>
</table>
Before adding the second query and the second table everything worked.
So basically what I want is when the is_active filter is equal to True the campaign should be in the first list. If it's False then it should jump to the other. Can anyone help me?
If request.method == "POST" but form_type_paused != 'campaign_status_paused', the formset_paused variable is never assigned. But you try to access it here:
...
paused_campaigns_and_forms = list(zip(queryset_paused, formset_paused))
...
That is where the error comes from.
Been struggling for weeks now with this issue, starting to feel like I will never solve it.
I have these methods under my model.
def sfget_totals(self):
return self.agent_sale.filter(Date_created__range=["2022-03-01","2022-04-02"]).count()
def sfget_confirmed(self):
return self.agent_sale.filter(State="Confirmed",Date_created__range=["2022-03-01","2022-04-02"]).count()
def sfget_debi(self):
return self.agent_sale.filter(AcknowledgeQA=True,State="Confirmed",Debi_status="Accepted",Date_created__range=["2022-03-01","2022-04-02"]).count()
def sfget_requested(self):
return self.agent_sale.filter(Debi_status="Requested",Date_created__range=["2022-03-01","2022-04-02"]).count()
def sfget_cancelled(self):
return self.agent_sale.filter(State="Cancelled",Date_created__range=["2022-03-01","2022-04-02"]).count()
def sfget_pending(self):
return self.agent_sale.filter(State="Pending",Date_created__range=["2022-03-01","2022-04-02"]).count()
in the above example i am putting the dates in manually(it works and returns the correct query)
problem is I still don't know how to make the user plug these dates in through the site.
This is my view.
def Team_stats(request,pk):
sd = request.GET.get("from")
ed = request.GET.get("to")
start_date = datetime.datetime.strptime(sd, "%Y-%m-%d").date()
end_date = datetime.datetime.strptime(ed, "%Y-%m-%d").date()
if start_date == None or end_date == None:
sales_agent = SalesAgent.objects.filter(Team_leader=pk)
return render(request,"Sales/Team_detail_page.html",{"sales_agent":sales_agent})
else:
sales_agent = SalesAgent.objects.filter(Team_leader=pk,agent_sale__Date_created__range=[start_date,end_date]).distinct()
print(type(start_date))
return render(request,"Sales/Team_detail_page.html",{"sales_agent":sales_agent})
This is my template.
I need to render all the agents under the team leader and the particular field of another model. For example State,Date_Created,Debi_status.
<form method="GET" action=".">
<div class="form-row">
<div class="form-group col-md-6">
<label for="inputEmail4">Start date</label>
<input type="date" format='%Y-%m-%d' name="from" class="form-control" id="inputEmail4" placeholder="Start Date">
</div>
<div class="form-group col-md-6">
<label for="inputEmail4">End date</label>
<input type="date" format='%Y-%m-%d' name="to" class="form-control" id="inputEmail4" placeholder="End date">
</div>
</div>
<button type="submit" class="btn btn-primary">Search</button>
</form>
<!-- <p>THERE SHOULD BE A GRAPH IN HERE FOR THE AGENTS STATS</p> -->
<br>
<br>
<div class="container">
<table class="table table-dark table-striped table-bordered">
<thead>
<tr>
<th scope="col">#</th>
<th scope="col">Agent Name</th>
<th scope="col">Total sales</th>
<th scope="col">Total debis</th>
<th scope="col">Total confirmed</th>
<th scope="col">Total requested</th>
<th scope="col">Total pending</th>
<th scope="col">Total cancelled</th>
</tr>
</thead>
{% for entry in sales_agent %}
<tbody>
<td>{{forloop.counter}}</td>
<td>{{entry.SA_name}}</td>
<td>{{entry.sfget_totals}}</td>
<td>{{ entry.sfget_debi}}</td>
<td>{{ entry.sfget_confirmed}}</td>
<td>{{ entry.sfget_requested}}</td>
<td>{{ entry.sfget_cancelled}}</td>
<td>{{ entry.sfget_pending}}</td>
{%endfor%}
</table>
<div>
<a type="button" class="btn btn-dark btn-m" href="{%url 'Sales:salesdash'%}">Go back</a>
{%endblock%}
I don't know how to do it better. It's not the best answer because you have to iterate through the entire queryset. But I think it works:
1- Change your models methods adding the variables "from" and "to":
#example
def sfget_totals(self, from, to): #
return self.agent_sale.filter(Date_created__range=[from,to]).count()
2- In your views.py, iterate and add the new properties to each item of the queryset:
def Team_stats(request,pk):
sd = request.GET.get("from")
ed = request.GET.get("to")
start_date = datetime.datetime.strptime(sd, "%Y-%m-%d").date()
end_date = datetime.datetime.strptime(ed, "%Y-%m-%d").date()
if start_date == None or end_date == None:
sales_agent = SalesAgent.objects.filter(Team_leader=pk)
return render(request,"Sales/Team_detail_page.html",{"sales_agent":sales_agent})
else:
sales_agent = SalesAgent.objects.filter(Team_leader=pk,agent_sale__Date_created__range=[start_date,end_date])
for s in sales_agent:
s.sfget_totals_prop = s.sfget_totals(start_date,end_date)
s.sfget_confirmed_prop = s.sfget_confirmed(start_date,end_date)
s.sfget_debi_prop = s.sfget_debi(start_date,end_date)
....
....
return render(request,"Sales/Team_detail_page.html",{"sales_agent":sales_agent})
3- In your templates, change the methods name by the new properties:
<td>{{entry.sfget_totals_prop}}</td>
<td>{{ entry.sfget_debi_prop}}</td>
<td>{{ entry.sfget_confirmed_prop}}</td>
<td>{{ entry.sfget_requested_prop}}</td>
<td>{{ entry.sfget_cancelled_prop}}</td>
<td>{{ entry.sfget_pending_prop}}</td>
Probably, you can solve the problem using Django Managers https://docs.djangoproject.com/en/4.0/topics/db/managers/ and you will find a better way.
I have a datatable in my django template in which there is a checkbox next to every row to send the row data to a view function to make some mass updations in django model. But problem is if the multiple rows are on the same page in pagination then i can send the data accurately BUT if i select row 2 from page 1 and row 5 from page 3 only the row value from page 3 will be sent to the view function.!
TEMPLATE.HTML
{% block jquery %}
<script type="text/javascript" class="init">
$(document).ready( function ($) {
var $submit = $("#updiv").hide(),
$cbs = $('input[name="updelegate"]').click(function() {
$submit.toggle( $cbs.is(":checked") );
});
$('#myTable').DataTable({
dom: 'lBfrtip',
"pageLength": 1,
"language": {
"emptyTable": "No Delegates Available",
"sSearch": "Search Delegates: ",
"info": " Showing _START_-_END_ out of Total _TOTAL_ Delegates",
}
});
});
</script>
{% endblock %}
<form id="myForm" action="{% url 'mass-delegates' %}" method="POST">
{% csrf_token %}
<table id="myTable" class="table table-striped table-bordered" style="width:100%">
<thead class="thead-dark">
<tr>
<th></th>
<th scope="col">#</th>
<th scope="col">Name</th>
<th scope="col">Email</th>
<th scope="col">Phone</th>
<th scope="col">Company</th>
<th scope="col">Designation</th>
<th scope="col">Address</th>
<th scope="col">City</th>
<th></th>
<th></th>
</tr>
</thead>
<tbody>
{% for del in delegates %}
<tr>
<td>
<label class="container">
<input type="checkbox" id="updelegate" name="updelegate"
value="{{ del.id }}">
<span class="checkmark"></span>
</label>
</td>
<td>{{ del.id }}</td>
<td>{{ del.first_name }} {{ del.last_name }}</td>
<td>{{ del.email }}</td>
<td>{{ del.phone }}</td>
<td>{{ del.company }}</td>
<td>{{ del.designation }}</td>
<td>{{ del.address }}</td>
<td>{{ del.city }} ({{ del.pincode }})</td>
<td>
View
</td>
<td>
Edit
</td>
</tr>
{% endfor %}
</tbody>
</table>
<div id="updiv">
<select name="eventid">
{% for ev in events %}
<option value="{{ ev.id }}">{{ ev.name }}</option>
{% endfor %}
</select>
<input type="submit" onclick="return confirm('Confirm Adding to Event?');" class="upbtn"
name="update" value="Add to Event"/>
</div>
</form>
VIEW.PY
def mass_delegates(request):
if request.method == 'POST':
toupdate = request.POST.getlist('updelegate')
eventid = request.POST.get('eventid')
array_length = len(toupdate)
for i in range(array_length):
if not EventDelegate.objects.filter(event_id=eventid, delegate_id=toupdate[i]).exists():
EventDelegate.objects.create(event_id=eventid, delegate_id=toupdate[i])
return event_det(request, eventid)
Instead of using the checkboxes, you can directly use the select attribute in the Datatables api. Check Select Rows in Datatables
Moreover, Since you want to select multiple rows at once, you might consider checking Multi Select rows in Datatables out
You can add the id in the 0th column, then
dataTable = $(.selector).Datatable()
dataTable.columns([0]).visible(false);
You can hide the column like that and then when you send your request, you still have your id
I've tried to google how to solve this problem.
But most of it was not related to this.
This program is to get input from user, which is in checkbox format, it will read all the content in text file and display it in table format on website.
QUESTION
Any possible command that the column only will be display if the column has value??
Note : If you understand and saw this problem before be please to post the link here.
THIS IS MY TEXT FILE
`delay_
775435
id 7754764
delay_
456345
id 64564
delay_
4567867867868
id 3453454
delay_
567867`
views.py
tokens = request.GET.getlist('token')
# ...
with open(path) as input_data:
for line in input_data:
if 'visual' in tokens and line.startswith('id_'):
prev_key = line.lstrip('id_').rstrip()
data.update({prev_key: []})
# you may want to continue to next line here - or not
# continue
if 'time' in tokens:
if search_string in line and prev_key in data:
data[prev_key].append(next(input_data).rstrip())
else:
if search_string in line:
prev_key = (next(input_data).rstrip())
data.update({prev_key:[]})
context = {'output': data,}
html table
<div class="input-group" align="center" style=" left:10px; top:-110px; width:99%">
<table class="table table-bordered">
<thead class="success" >
<tr>
<th class="success">
<b>Visual ID</b>
</th>
<th class="success">
<b>Time Delay Index Time</b>
</th>
</tr>
{% for key, values in output.items %}
<tr class="warning">
<td rowspan={{ values|length|add:1 }}><b>{{ key }}</b></td>
{% for value in values %}
<tr class="warning">
<td ><b>{{value}}{{key1}}</b></td>
</tr>
{% endfor %}
</tr>
{% endfor %}
</thead>
</table>
</div>
REFERENCE
In the template wrap the <th> definition in if block:
{% if output.your_key %}
<th class="success">
<b>Whatever you want </b>
</th>
# and so on
{% endif %}
So if the key is present in your output, you'll create a corresponding header, if not, you won't.
I am trying to get a value inputted through a form and then back into my jinja template. Which I know doesn't make sense so I guess I am asking how do I go about doing what I want?. Here is what I have:
Python
#app.route('/test', methods=['GET', 'POST'] )
def test():
posts = db.posts
facultyId = request.form.get("facultyId","");
print "facultyId: ",facultyId
return render_template('form.html',posts=posts,Id=facultyId)
form.html
<form method='post'>
<table width="80%" border="5" align="center" bgcolor="white">
<tbody>
<tr>
<th colspan= "4">
Faculty Identification Number:
<input type="text" id="facultyId" name="facultyId" value=""/>
</th>
</tr>
<tr>
<th colspan= "4">
Number Of Evaluations:
{% if posts.find({"Applicants.appId" : Id},{'Applicants.Evaluators':{'$exists': True }}).count() == 0 %}
{{posts.find({"Applicants.appId" : Id},{'Applicants.Evaluators':{'$exists': True }}).count() }}
{% else %}
{% for post in posts.find({"Applicants.appId" : Id}, { "Applicants.$.Evaluators" : 1 }) %}
{{post["Applicants"][0]["Evaluators"]|length}}
{% endfor %}
{% endif %}
</th>
</tr>
<th colspan= "4"><button type="submit" >Submit</button></th>
</tbody>
</table>
</form>
I want to be able to submit a facultyId though a form and have it go into my jinja and run my mongodb find query. It works if I hard code the value in so if I did Id=100 in my python it works but if I do it though the forums it doesn't and the facultyId value is getting inputted because it does prints out.
Try to set action controller as follows
<form method='post' action='/test'>
I think the problem is that you do not parse facultyId as an integer. It works if you hardcode 100, because it is an integer, but what you assign out of request.form is a string "100".
After
facultyId = request.form.get("facultyId","")
add
facultyId = int(facultyId) if facultyId else None
Try to put it in braces. Like this:
<form method='post'>
<table width="80%" border="5" align="center" bgcolor="white">
<tbody>
<tr>
<th colspan= "4">
Faculty Identification Number:
<input type="text" id="facultyId" name="facultyId" value=""/>
</th>
</tr>
<tr>
<th colspan= "4">
Number Of Evaluations:
{% if posts.find({"Applicants.appId" : {{Id}}},{'Applicants.Evaluators':{'$exists': True }}).count() == 0 %}
{{posts.find({"Applicants.appId" : {{Id}}},{'Applicants.Evaluators':{'$exists': True }}).count() }}
{% else %}
{% for post in posts.find({"Applicants.appId" : {{Id}}}, { "Applicants.$.Evaluators" : 1 }) %}
{{post["Applicants"][0]["Evaluators"]|length}}
{% endfor %}
{% endif %}
</th>
</tr>
<th colspan= "4"><button type="submit" >Submit</button></th>
</tbody>
</table>
</form>
I would also suggest to put your posts.find logic into your route function, then pass it's results to your form in the posts variable.