I have a list of parts (model 1) with prices (model 2). I want to display them in a django-tables2 table to get the historic prices of a part in a table:
models.py:
class Parts(models.Model):
name = models.CharField('Name', max_length=120, unique=True)
class Prices(models.Model):
price = models.DecimalField("Price", decimal_places=2, max_digits=8)
date = models.DateTimeField(default=timezone.now)
part = models.ForeignKey(Parts, on_delete=models.CASCADE)
tables.py:
class PriceHistoryTable(django_tables2.Table):
price = django_tables2.Column(accessor="prices_list", verbose_name="Price",)
date = django_tables2.Column(accessor="dates_list", verbose_name="Date",)
class Meta:
model = Parts
sequence = ("date", "price",)
I tried to create the tables from two lists as I thought the docs would suggest here (list of dicts) using these methods in the models:
def dates_list(self):
return [{"date": d.date} for d in Prices.objects.filter(part_id = self.id)]
def prices_list(self):
return [{"price": p.price} for p in Prices.objects.filter(part_id = self.id)]
But then I end up with a table in django-tables2 that contains the complete list of dates and prices in just one row.
How would a method look that creates a queryset for the prices and one for the dates, so I can use it for django-tables2?
edit for the solution:
views.py
class PartTable(SingleTableView):
model = Parts
template_name = "gap/parts_detail.html"
table_class = PartPriceHistoryTable
queryset = Parts.objects.annotate(date=F("prices__date"),
price=F("prices__price")).order_by('price', 'date')
tables.py:
class PriceHistoryTable(django_tables2.Table):
price = django_tables2.Column(accessor="price", verbose_name="Price",)
date = django_tables2.Column(accessor="date", verbose_name="Date",)
class Meta:
model = Parts
sequence = ("date", "price",)
models.py stays as above
You can try to annotate the value of date and price with queryset using F()
expression, and access it through accessor(or not, just define the field name same as annotated variable) in the table. For example:
# table class
class PriceHistoryTable(django_tables2.Table):
price = django_tables2.Column(accessor="price", verbose_name="Price",)
date = django_tables2.Column(accessor="date", verbose_name="Date",)
class Meta:
model = Parts
sequence = ("date", "price",)
# example implementation
from django.db.models import F
queryset = Parts.objects.annotate(date=F('prices__date'), price=F('price__price')).order_by('parts', 'date')
table = PriceHistoryTable(queryset)
for item in table.as_values():
print(item)
# view
class PartTable(SingleTableView):
template_name = "gap/parts_detail.html"
table_class = PartPriceHistoryTable
table_pagination = {"per_page": 10}
queryset = Parts.objects.annotate(date=F("prices__date"), price=F("prices__price")).order_by('price', 'date')