I am working on a project for a Django course I am taking but currently struggling a bit with views.
In the project I created a View using ListView to display a list of products in my template. By using query_set I am able to get all the objects and return them to display all the products and their attributes in the template by using a for loop.
In the same query_set, I tried returning another variable that contains the total items in stock to display this data in the template as well, however, as soon as I add this variable to the return the template no longer receives the returned values.
This is the code I tried to return both values:
class ShopListing(ListView):
template_name = "webshop/shop_listing.html"
context_object_name = 'shop_listing'
def get_queryset(self):
#Get all products
products = Product.objects.all()
total_stock = products.aggregate(sum=Sum('stock'))['sum']
return products, total_stock
In my template I added the value 'total_stock' as shown below but I get nothing, and even the values from 'products' stop working:
<p><strong>{{total_stock}}</strong> items are currently available</p>
If I remove 'total_stock' from the return everything goes back to normal.
If I print "total_stock" I can see the right value in the logs, but this cannot be used in my template so I wonder what is the right way to do this.
Will appreciate any guidance.
I suspect this is because of the machinery behind get_queryset()
. By returning an additional value, you're actually returning a tuple
to the view class methods that internally call get_queryset()
. You can take a look at the Django source code for ListView
and its related classes to see how they work with models and template context variables behind the scenes.
Given your description, however, I think you want to extend the get_context_data()
method instead:
class ShopListing(ListView):
template_name = "webshop/shop_listing.html"
context_object_name = 'shop_listing'
queryset = Product.objects.all()
def get_context_data(self, **kwargs):
context = super().get_context_data(**kwargs)
context['total_stock'] = Product.objects.aggregate(sum=Sum('stock'))['sum']
return context
'total_stock'
should be available as a template variable, along with the intended QuerySet
.