I'm trying to get cart total sum of products in the html template, while the the total sum of particular products works fine, the cart total price/quantity shows blank spaces.
Models:
from django.db import models
import Accounts.models as accounts_models
import Products.models as products_models
class Order(models.Model):
customer = models.ForeignKey(accounts_models.Customer, on_delete=models.SET_NULL, blank=True, null=True)
date_ordered = models.DateTimeField(auto_now_add=True)
complete = models.BooleanField(default=False)
transaction_id = models.CharField(max_length=100, null=True)
def __str__(self):
return str(self.id)
#property
def get_cart_total(self):
orderproducts = self.orderproduct_set.all()
total = sum([product.get_total for product in orderproducts])
return total
#property
def get_cart_products(self):
orderproducts = self.orderproduct_set.all()
total = sum([product.quantity for product in orderproducts])
return total
class OrderProduct(models.Model):
product = models.ForeignKey(products_models.Products, on_delete=models.SET_NULL, blank=True, null=True)
order = models.ForeignKey(Order, on_delete=models.SET_NULL, blank=True, null=True)
quantity = models.IntegerField(default=0, null=True, blank=True)
date_added = models.DateTimeField(auto_now_add=True)
#property
def get_total(self):
total = self.product.price * self.quantity
return total
views:
def cart(request):
if request.user.is_authenticated:
customer = request.user.customer
order, created = Order.objects.get_or_create(customer=customer, complete=False)
items = order.orderproduct_set.all()
else:
items = []
context = {'items': items}
return render(request, 'cart.html', context)
html template:
{% for item in items %}
<tr>
<td>{{ item.product.name }}</td>
<td>{{ item.quantity }}</td>
<td>${{ item.product.price }}</td>
<td>${{ item.get_total }}</td>
</tr>
{% endfor %}
<tr>
<td colspan="3"><strong>Total:</strong></td>
<td>${{ order.get_cart_total }}</td>
</tr>
How can I start showing the total numbers in the html template?
You didn't pass order in your cart view, here is updated view:
def cart(request):
if request.user.is_authenticated:
customer = request.user.customer
order, created = Order.objects.get_or_create(customer=customer, complete=False)
items = order.orderproduct_set.all()
else:
items = []
order = None # Add this line to handle the case when there is no order
context = {'items': items, 'order': order} # Add the order object to the context dictionary
return render(request, 'cart.html', context)
Related
I am building menu items for Irvine class and want to categorize them by Category
models.py
class Irvine(models.Model):
objects = None
name = models.CharField(max_length=50, verbose_name='Irvine Item')
description = models.TextField(null=True, blank=True)
size = models.FloatField(null=True, blank=True)
price = models.FloatField(null=True, blank=True)
published = models.DateTimeField(auto_now_add=True, db_index=True)
category = models.ForeignKey('Category', null=True, on_delete=models.PROTECT, verbose_name='Category')
def __str__(self):
return self.name
class Meta:
verbose_name_plural = 'Irvine'
verbose_name = 'Irvine Item'
ordering = ['-published']
class Category(models.Model):
objects = None
name = models.CharField(max_length=30, db_index=True, verbose_name="Category")
published = models.DateTimeField(auto_now_add=True, db_index=True)
def __str__(self):
return self.name
class Meta:
verbose_name_plural = '* Categories'
verbose_name = 'Category'
ordering = ['name']
view.py
def irvine(request):
irvine = Irvine.objects.all()
context = {'irvine': irvine}
return render(request, 'cafe/irvine.html', context)
def by_category(request, category_id):
santaanna = SantaAnna.objects.filter(category=category_id)
costamesa = CostaMesa.objects.filter(category=category_id)
irvine = Irvine.objects.filter(category=category_id)
categories = Category.objects.all()
current_category = Category.objects.get(pk=category_id)
context = {'santaanna': santaanna, 'categories': categories, 'costamesa': costamesa, 'irvine': irvine, 'current_category': current_category}
return render(request, 'cafe/by_category.html', context)
urls.py
urlpatterns = [
path('add/', ItemsCreateView.as_view(), name='add'),
path('<int:category_id>/', by_category, name='by_category'),
path('', index, name='index'),
path('irvine', irvine),
with
{% for i in irvine %}
{}
<tr class="danger">
<th scope="row" width="20%">{{ i.name }}</th>
<td width="60%">{{ i.description }}</td>
<td width="10%">{{ i.size }}</td>
<td width="10%">{{ i.price }}</td>
</tr>
{% endfor %}
I can grab all items from class Irvine, but how do i get items from this class by category
You can't directly check using i.category because it has list of values.
Try using i.category.name.
If you have serializer, please update the full code.
{% for i in irvine %} {% if i.category.name == 'Appetizers' %}, it will work
At the very beginning I would note that I'm a beginner as hel :P I have two models in my django models.py and I want them to display on a page. The issue is that I got error about no possible iteration and I don't know why.
Also, I'm following the Crash Course from Youtube with changing some thing for my use :)
Could You please advice as I haven't found any useful tips on google?
Thanks!
models.py
from django.db import models
# Create your models here.
class Supplier(models.Model):
name = models.CharField(max_length=200, null=True)
phone = models.CharField(max_length=200, null=True)
email = models.CharField(max_length=200, null=True)
date_created = models.DateTimeField(auto_now_add=True)
def __str__(self):
return self.name
class Order(models.Model):
STATUS = (
('Pending Order', 'Pending Order'),
('Pending PR', 'Pending PR'),
('Declined by SME', 'Declined by SME'),
('Declined by Finance', 'Declined by Finance'),
('Ordered', 'Ordered'),
('Canceled', 'Canceled'),
('Delivered', 'Delivered'),
)
product = models.CharField(max_length=200, null=True)
link = models.CharField(max_length=400, null=True)
supplier = models.ForeignKey(Supplier, null=True, on_delete=models.SET_NULL)
date_created = models.DateTimeField(auto_now_add=True, null=True)
status = models.CharField(max_length=200, null=True, default='Pending Order', choices=STATUS)
amount = models.CharField(max_length=40, null=True)
comment = models.CharField(max_length=400, null=True, blank=True)
requester = models.CharField(max_length=40, null=True)
def __str__(self):
return self.product
views.py
from django.shortcuts import render
from .models import *
# Create your views here.
def home(request):
return render(request, 'accounts/dashboard.html')
def products(request):
return render(request, 'accounts/products.html')
def customer(request):
return render(request, 'accounts/customer.html')
def orders(request):
orders = Order.objects.all()
customers = Supplier.objects.all()
context = {'orders': orders, 'customers': customers}
return render(request, 'accounts/orders.html', {'orders': Order})
And a part of my HTML which is only bootstrap and HTML
<table class="table table-sm">
<tr>
<th>Supplier</th>
<th>Product (Name)</th>
<th>Product (ID)</th>
<th>Date Orderd</th>
<th>Status</th>
<th>Requester</th>
<th>Update</th>
<th>Remove</th>
</tr>
{% for order in orders %}
<tr>
<td>{{order.supplier}}</td>
<td>{{order.product}}</td>
<td>{{order.link}}</td>
<td>{{order.date_created}}</td>
<td>{{order.status}}</td>
<td>{{order.requester}}</td>
{% endfor %}
</table>
def orders(request):
orders = Order.objects.all()
customers = Supplier.objects.all()
context = {'orders': orders, 'customers': customers}
return render(request, 'accounts/orders.html', context)
Try this.
In render you're passing the Order class instead of your queryset orders
I've create 3 models for the Order processing. However, I couldn't show the product name on template for every single order. Does my for loop logic or 'get' method go wrong?
models.py:
class Product(models.Model):
product_name = models.CharField(max_length=200)
price = models.DecimalField(decimal_places=2, max_digits=10, blank=True)
created = models.DateTimeField(auto_now=True)
slug = models.SlugField(max_length=255, unique=True)
def __str__(self):
return self.product_name
class OrderItem(models.Model):
user = models.ForeignKey(settings.AUTH_USER_MODEL, on_delete=models.CASCADE, blank=True, null=True)
item = models.ForeignKey(Product, on_delete=models.CASCADE)
quantity = models.IntegerField(default=1)
ordered = models.BooleanField(default=False)
def __str__(self):
return f"{self.quantity} of {self.item.product_name}"
class Order(models.Model):
user = models.ForeignKey(settings.AUTH_USER_MODEL, on_delete=models.CASCADE, blank=True, null=True)
items = models.ManyToManyField(OrderItem)
start_date = models.DateTimeField(auto_now_add=True)
ordered = models.BooleanField(default=False)
def __str__(self):
return self.user.username
view.py:
def user_info(request):
orders = Order.objects.filter(user=request.user, ordered=True).order_by('-start_date')
context = {
'orders': orders,
}
return render(request, 'home.html', context)
home.html:
{% for order_item in orders.items.all %}
<p>{{ order_item.item.product_name }}</p>
{% endfor %}
You are passing orders from your view which is a queryset so you can't do orders.items.all. You should do a for loop to loop over orders and then get the items:
{% for order_item in orders %}
<p>product names for order id {{order_itme.id}}:</p>
{% for item in order_item.items.all %}
<p>{{ item.item.product_name }}</p>
{% endfor %}
{% endfor %}
Note that this will renders all items for all orders. You should filter the result if you just need one or some of them.
I am trying to get the total no. of a sold item after payment is made.
When the order is paid ordered = models.BooleanField(default=False) become True
I have tried to add the context with the total sold but it didn't work so I kept it in the code below but commented it.
I have also tried to add a function with total count but I keep getting 'Item' object has no attribute 'order_set' I kept it below for reference
Here is the Item models.py
class Item(models.Model):
title = models.CharField(max_length=100)
def __str__(self):
return self.title
# def count_sold(self):
# return self.order_set.filter(ordered=True).count()
Here is the OrderItemmodels.py
class OrderItem(models.Model):
ordered = models.BooleanField(default=False)
item = models.ForeignKey(Item, on_delete=models.CASCADE)
Here is the Order
class Order(models.Model):
items = models.ManyToManyField(OrderItem)
ordered = models.BooleanField(default=False)
Here is the views.py
class DesignerOnlyPostListView(ListView):
model = Item
template_name = "designer_only_posts.html"
context_object_name = 'items'
paginate_by = 6
def get_queryset(self):
user = get_object_or_404(User, username=self.kwargs.get('username'))
return Item.objects.filter(designer=user).order_by('-timestamp')
def get_context_data(self, **kwargs):
comments = Comment.objects.all()
# total_sold = Order.objects.all()
context = super().get_context_data(**kwargs)
context["total_comments"] = comments.count()
# context["total_sold"] = total_sold.count()
return context
Here is the template
{% for item in items %}
<tr>
<td>No. of Sold:</td>
<td>{{ item.total_sold.all.count }}</td>
</tr>
{% endfor %}
This is the template when I tried to use the function for count_sold
<tr>-->
<!-- <td>No. of Reviews:</td>-->
<!-- <td>{{ item.count_sold }}</td>-->
<!-- </tr>
Item doesn't have order_set, because there's no relation between those two Models.
Item is related to OrderItem
OrderItem is related to Order
Maybe you can try something like:
class Item(models.Model):
title = models.CharField(max_length=100)
def __str__(self):
return self.title
#property
def count_sold(self):
return self.orderitem_set.filter(ordered=True).count()
and for the template
{% for item in items %}
<tr>
<td>No. of Sold:</td>
<td>{{ item.count_sold }}</td>
</tr>
{% endfor %}
I have the following view where I want to return the quantity of the current cart entry.
def test_view(request):
cart_obj, new_obj = Cart.objects.new_or_get(request)
my_carts_current_entries = Entry.objects.filter(cart=cart_obj)
product_quantity = request.POST.get('product_quantity')
return render(request, 'carts/test.html', {'my_cart': cart_obj, 'my_carts_current_entries': my_carts_current_entries})
How would I reference the current entry quantity, e.g. if there is an entry in the database called 23x Chicken Nuggets I want it to return the quantity.
On the template if I return:
{{ my_carts_current_entries }}
it will return all the current entries but without the quantity.
For clarity I have included an extract of my models.py from the said application:
class Cart(models.Model):
user = models.ForeignKey(User, null=True, blank=True)
count = models.PositiveIntegerField(default=0)
total = models.DecimalField(default=0.00, max_digits=10, decimal_places=2)
updated = models.DateTimeField(auto_now=True)
timestamp = models.DateTimeField(auto_now_add=True)
objects = CartManager()
def __str__(self):
return "Cart:{} User:{} Items:{} Total:£{}".format(self.id, self.user, self.count, self.total)
class Entry(models.Model):
product = models.ForeignKey(Product, null=True)
cart = models.ForeignKey(Cart, null=True)
quantity = models.PositiveIntegerField(default=0)
def __str__(self):
return self.product.name
try this in template:
{% for cart in my_carts_current_entries %}
{{ cart.product }} - {{ cart.quantity }}
{% endfor %}