I have 2 models; one is for material definition and the other is for stocks tracking. I need a stocks table because there will be same materials with different expiry date. I m using a django generic listview and want to modify queryset to display a summary list of materials quantities will be summed.
for expample :
stocks_table:
name packing_details expiry_date quantity
milk 1lt boxes 11/11/2019 30
milk 1lt boxes 12/12/2019 40
after modifiying the queryset :
name packing_details quantity
milk 1lt boxes 70
is it possible with the generic listview or should i prepare a function based view ?
Models
class Material(models.Model):
name = models.CharField(max_length=500)
packing_details = models.CharField(max_length=500)
material_unit = models.CharField(max_length=3)
class Stock(models.Model):
material = models.ForeignKey(Material, on_delete=models.CASCADE)
expiry_date = models.DateField()
quantity = models.DecimalField(max_digits=10, decimal_places=2)
price = models.DecimalField(max_digits=10, decimal_places=2)
date_created = models.DateField(default=timezone.now)
created_by = models.ForeignKey(User, on_delete=models.CASCADE, default=1)
View
class StocksListView(LoginRequiredMixin, ListView):
model = Stock
context_object_name = 'stocks'
Template
{% for stock in stocks %}
<tr>
<td class="text-center">{{ stock.material.name }}</td>
<td class="text-center">{{ stock.material.packing_details }}</td>
<td class="text-center">{{ stock.quantity }}</td>
<td class="text-center">{{ stock.price }}</td>
</tr>
{% endfor %}
Wherever you do this, you actually need to flip the query; you need to get a list of Materials, and sum their stock quantities.
So:
from django.db.models import Sum
Material.objects.annotate(quantity=Sum('stock__quantity')).filter(quantity__gt=0)
You can set that directly as the queryset in the view:
class StocksListView(LoginRequiredMixin, ListView):
queryset = Material.objects.annotate...
You'll need to update your template now that you're starting from Material instead of Stock.