So basically in my store, every item has a specific weight and once the customer adds whatever they want and go to checkout, they can see every single order of theirs along with the name information and weight. I want to also add the total weight of all the items together. Currently, it displays only the weight of each particular item.For exampleItem A is 2 Kg and item B is 3 kgIf customer adds 2 item A and 3 Item B It displays Item: A quantity: 2 Weight : 4kgItem: B quantity: 3 Weight: 9kg.I want to also add Total weight : 13 kg
This is my views.py
def checkout(request):
try:
current_order = Order.objects.filter(owner=1).get(status="pre-place")
except Order.DoesNotExist:
return HttpResponse("Your current order is empty<br>Go back")
else:
total_weight = 0
items = OrderDetail.objects.filter(orderID=current_order)
template_name = 'store/checkout.html'
order_details = []
for item in items:
weight = item.supplyID.weight * item.quantity
order_details.append((item, weight))
return render(request, template_name, {'order_details': order_details, 'current_order': current_order})
This is my template
<h1>Your current order</h1>
<a href="{% url 'Store:browse' %}">return to selecting
supplies</a><br><br>
<table>
<tr><th>name</th><th>item weight(kg)</th><th>qty</th><th>total
weight(kg)</th></tr>
{% for order_detail, weight in order_details %}
<tr>
<td>{{ order_detail.supplyID.name }}</td>
<td>{{ order_detail.supplyID.weight }}</td>
<td>{{ order_detail.quantity }}</td>
<td>{{ weight }}</td>
</tr>
{% endfor %}
</table>
Documentation
The context variable passed to render just has to be a dictionary , so you can do your computation of the Total Weight in views.py, place this value in the dictionary and then grab the value of the Total Weight key in your template.
For example:
def checkout(request):
try:
current_order = Order.objects.filter(owner=1).get(status="pre-place")
except Order.DoesNotExist:
return HttpResponse("Your current order is empty<br>Go back")
else:
total_weight = 0
items = OrderDetail.objects.filter(orderID=current_order)
template_name = 'store/checkout.html'
order_details = []
for item in items:
weight = item.supplyID.weight * item.quantity
order_details.append((item, weight))
total_weight +=weight
return render(request, template_name, {'order_details': order_details, 'current_order': current_order, 'Total Weight' : total_weight})
Then just use that variable in your template:
<h1>Your current order</h1>
return to selecting supplies<br><br>
<table>
<tr>
<th>name</th><th>item weight(kg)</th><th>qty</th><th>total weight(kg)</th>
</tr>
{% for order_detail, weight in order_details %}
<tr>
<td>{{ order_detail.supplyID.name }}</td>
<td>{{ order_detail.supplyID.weight }}</td>
<td>{{ order_detail.quantity }}</td>
<td>{{ weight }}</td>
</tr>
{% endfor %}
</table>
<p>The total weight of your order is:</p>
<p>{{Total Weight}}</p>
First, you should understand the difference between get() and filter(). Take a look at this.
After that we can make some changes:
def checkout(request):
try:
current_order = Order.objects.filter(owner__exact=1, status__icontains ="pre-place") # exact returns exact match, icontains(could have been iexact too if you want exact match) return not case sensitive match.
except Order.DoesNotExist:
return HttpResponse("Your current order is empty<br>Go back")
else:
items = OrderDetail.objects.filter(orderID__exact=current_order) #since it is id no need for iexact which is case insensitive.
order_details = {} # it is always suggestible to use dictionary instead of turple for easiness.
for item in items:
weight = item.supplyID.weight * item.quantity
order_details[item] = weight
total_weight = sum(order_detail.values()) #sum of total weight
context = { #clear to read and maintain
'order_details': order_details,
'current_order': current_order,
'total_weight': total_weight
}
return render(request,
'store/checkout.html', # i don't find storing url usefull
context=context)
This is your template:
<h1>Your current order</h1>
<a href="{% url 'Store:browse' %}">return to selecting
supplies</a><br><br>
<table>
<tr><th>name</th><th>item weight(kg)</th><th>qty</th><th>total
weight(kg)</th></tr>
{% for item, weight in order_details.items() %}
<tr>
<td>{{ item.supplyID.name }}</td>
<td>{{ item.supplyID.weight }}</td>
<td>{{ item.quantity }}</td>
<td>{{ weight }}</td>
</tr>
{% endfor %}
</table>
Related
I have a checkbox pagination where user select some of the option after user submit he get redirect to the page where he sees what all item he selected and value of the item , I want to get the sum of the value of item he selected .
<tbody>
{% for booktest in var1 %}
<tr>
<td width="100%">{{ booktest }}</td>
<td>{{ booktest.rate }}</td>
</tr>
{% endfor %}
</ul>
</tbody>
Above is the HTMl code where i get select item and i want to add all value in {{ booktest.rate }}
views.py
def ResultTest(request):
var = request.POST.get('selectedTests')
booktests = BookTest.objects.filter(test__in=var.split(','))
views.py from where i get selected checkbox data.
You can calculate the sum of the rates with the Sum aggregate function [Django-doc]:
from django.db.models import Sum
def result_test(request):
var = request.POST.get('selectedTests')
booktests = BookTest.objects.filter(test__in=var.split(','))
total_rate = booktests.aggregate(total=Sum('rate'))['total'] or 0
# …
I am having trouble getting the code to properly display the portfolio in index.html.
My logic with this function is to get a list of all the stocks and cash one user has, and then in a "for" loop, look up the company name and current price for each stock, the total value, and then insert all of that information into a new list of dictionaries (display_portfolio). Then the render_template should display "display_portfolio" with this information, as well as the user's total cash and total value of everything. However, with my current setup, it is displaying the total cash and grand total, but nothing from the individual stocks. I am really not sure why that is, and I am unsure if the issue is in my html or in the flask function itself.
This is the function:
#app.route("/")
#login_required
def index():
"""Show portfolio of stocks"""
# Retrive portfolio
portfolio = db.execute("SELECT symbol, SUM(amount) as amount FROM purchases WHERE id = ? ORDER BY symbol", (session["user_id"]))
user_cash = db.execute("SELECT cash FROM users WHERE id = ?", session["user_id"])
cash = user_cash[0]["cash"]
display_portfolio = []
shares_total = 0
# loop through portfolio symbols to access name and share price for each symbol
for row in portfolio:
requested_quote = lookup(row["symbol"])
symbol = row["symbol"]
amount = row["amount"] #shares
price = float(requested_quote["price"])
name = requested_quote["name"]
share_total = (float(amount) * price)
shares_total = shares_total + share_total
display_portfolio.append({'symbol':symbol, 'name':name, 'shares':amount, 'price':price, 'share_total':share_total})
grand_total = shares_total + cash
return render_template("index.html", display_portfolio = display_portfolio, cash = cash, grand_total = grand_total)
This is index.html:
{% extends "layout.html" %}
{% block title %}
Portfolio
{% endblock %}
{% block main %}
<div>
<table class="table table-striped">
<thead>
<tr>
<th>Symbol</th>
<th>Name</th>
<th>Shares</th>
<th>Price</th>
<th>TOTAL</th>
</tr>
</thead>
<tfoot>
<tr>
<td colspan="3"></td>
<td>TOTAL</td>
<td>{{ grand_total | usd }}</td>
</tr>
</tfoot>
<tbody>
{% for row in display_portfolio %}
<tr>
<td>{{ display_portfolio.symbol }}</td>
<td>{{ display_portfolio.name }}</td>
<td>{{ display_portfolio.shares }}</td>
<td>{{ display_portfolio.price }}</td>
<td>{{ display_portfolio.total }}</td>
</tr>
{% endfor %}
<td colspan="3"></td>
<td>Cash</td>
<td>{{ cash | usd }}</td>
</tbody>
</table>
</div>
{% endblock %}
I should also note, that when I add "| usd" to "display_portfolio.price" in that it reads:
<td>{{ display_portfolio.price | usd }}</td>
I am also getting a completely separate error, and not sure why it would work with cash and not this.
I can confirm that there exists purchases in the sql database the "portfolio" variable is retrieving.
This is what it looks like:
Display
Any help will be appreciated, thanks!
From MDN doc on tfoot:
Permitted parents: A <table> element. The <tfoot> must appear after
any <caption>, <colgroup>, <thead>, <tbody>, or <tr> element. Note
that this is the requirement as of HTML5.
Suspect the Cash line is displayed because it is missing <tr> tags.
Nu HTML Validator from W3C is your friend :)
This might be a confusing question.
I have three tables in sqllite: 1) Events 2) Delegates 3) EventDelegate
1st one stores all events, 2nd one stores all delegates, 3rd one contains the eventid and delegateid to show that the particular delegate is attending that particular event.
In my event details page i only want to show the delegates whose id are present in the event_delegate table along with that event id. Currently im using this code but not working
views.py
def event_det(request, eid):
data = Event.objects.filter(id=eid) //SELECTING ONLY THE CLICKED EVENT
data2 = Delegate.objects.all() // SELECTING ALL THE DELEGATES FROM DB
data3 = EventDelegate.objects.filter(event_id=eid) //SELECTING RECORDS FROM EVENT_DELEGATE WHERE eventid is eid
return render(request, 'event_details.html', {'event': data, 'delegates': data2, 'selectdelegates': data3})
template
<tbody>
{% for del in delegates %}
{% for sd in selectdelegates %}
{% if del.id == sd.delegate_id %}
<tr>
<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>View</td>
</tr>
{% endif %}
{% endfor %}
{% endfor %}
</tbody>
I can share more details if required...
If you have a relationship between event and event delegate like this:
class EventDelegate(models.Model):
event = models.ForeignKey(Event, on_delete=models.DO_NOTHING)
delegate = models.ForignKey(Delegate, on_delete=models.DO_NOTHING)
Then you can try like this:
def event_det(request, eid):
data = Event.objects.get(id=eid) //SELECTING ONLY THE CLICKED EVENT
return render(request, 'event_details.html', {'event': data})
# template
{% for e in event.eventdelegate_set.all %}
<tr>
<td>{{ e.delegate.id }}</td>
<td>{{ e.delegate.first_name }} {{ e.delegate.last_name }}</td>
<td>{{ e.delegate.email }}</td>
<td>{{ e.delegate.phone }}</td>
<td>{{ e.delegate.company }}</td>
<td>{{ e.delegate.designation }}</td>
<td>View</td>
</tr>
{% endfor %}
Alternative solution:
#view
def event_det(request, eid):
data = EventDelegate.objects.filter(id=eid) //SELECTING ONLY THE CLICKED EVENT
return render(request, 'event_details.html', {'event_delegates': data})
# template
{% for e in event_delegates %}
// rest of the code as above example
More information can be found in documentation.
If I understand right, EventDelegate models have ForeignKey to an Event and to a Delegate. So what you want is a queryset of EventDelegate objects that are linked to the event in question.
ed_qs = EventDelegate.objects.filter( event_id = event.id )
(maybe add .order_by( "delegate__lastname") for alpha ordering and .select_related()
pass this to your template, and
<tbody>
{% for ed in ed_qs %}
<tr>
{{ed.delegate.whatever}} ...
Alternatively you might use .annotate in the queryset to copy the desired fields of the linked delegate onto the returned objects. You'd then refer to the annotations, via your chosen annotation names such as {{ed.delegate_firstname}}.My guess is that this would be maximally efficient, if that matters.
I would like to compute the total of a shopping cart in my template:
This is my template with a table of products.
I tried to use a Generator expression in my cart method but it doesn't work.
Any thoughts?
cart.html
<table>
{% if not cart_list %}
{{ "The cart is empty" }}
{% else %}
<tr>
<th>Name</th>
<th>Price</th>
</tr>
{% for product in cart_list %}
<tr>
<td>{{ product.name }}</td>
<td>${{ product.price }}</td>
</tr>
{% endfor %}
<tr>
<td>{{ Total }}</td>
<td>{{ total_prices }}</td>
</tr>
{% endif %}
</table>
views.py
def cart(request):
if request.method == 'GET':
cart_list = Product.objects.filter(in_cart = True)
total_prices = sum(product.price for product in cart_list)
template_cart = loader.get_template('cart/cart.html')
context = {'cart_list': cart_list}
return HttpResponse(template_cart.render(context, request))
Add your total_prices to context variable, if you want it to be visible in the template.
def cart(request):
if request.method == 'GET':
...
total_prices = sum(product.price for product in cart_list)
context = {
'cart_list': cart_list,
'total_prices': total_prices
}
return HttpResponse(template_cart.render(context, request))
But you can try to use aggregate, something like this.
from django.db.models import Sum
Product.objects.filter(in_cart=True).aggregate(Sum('price'))
# you will have something like this -> 34.35 is example
# {'price__sum': 34.35}
I want to get all the details of class Material where user=user_id
Here is the models.py:
class Material(models.Model):
subject = models.CharField(max_length=10)
topic = models.CharField(max_length=50)
user = models.IntegerField()
and my views.py:
def add_material(request):
c = {}
c.update(csrf(request))
if 'user_session' in request.session:
user_id = request.session['user_session']
material_array = Material.objects.filter(user=user_id).values()
materials_len = len(material_array)
c['m_len'] = materials_len
for i in range(0, materials_len):
c['material_id_'+str(i)] = material_array[i]
return render_to_response('add_material.html',c)
else:
return HttpResponseRedirect('/user')
and my add_material.html is:
{% for i in range(m_len) %}
<tr>
{% for j in material_id_+str(i) %}
{{j.subject}}
{{j.topic}}
{% endfor %}
</tr>
{%endfor%}
So I am getting error in template, how to insert variable in for loop?
This how I would do it.
views.py
def add_material(request):
c = {}
c.update(csrf(request))
if 'user_session' in request.session:
user_id = request.session['user_session']
material_array = Material.objects.filter(user=user_id)
c.update({'materials': material_array})
return render_to_response('add_material.html', c)
else:
return HttpResponseRedirect('/user')
template
{% for material in materials %}
<tr>
<td>{{ material.subject }}</td>
<td>{{ material.topic }}</td>
<td>{{ material.user.username }}</td>
</tr>
{% endfor %}
You can include any user field you like.