单个表的两个模型的查询集

时间:2020-07-22 08:49:11

标签: django django-models django-tables2

我有一个零件清单(型号1)和价格(型号2)。我想将它们显示在django-tables2表中,以获取表中零件的历史价格:

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",)

我试图从两个列表中创建表,因为我认为文档会建议使用模型中的以下方法here (list of dicts)

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)]

但是后来我在django-tables2中得到一个表,该表仅在一行中包含日期和价格的完整列表。

如何为价格创建一个查询集,为日期创建一个查询集,以便可以将其用于django-tables2?

编辑解决方案:

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保持不变

1 个答案:

答案 0 :(得分:2)

您可以尝试使用F() expression通过queryset注释日期和价格的值,并通过表中的访问器(或不定义,只需将字段名称与注释变量相同)进行访问。例如:

void OnTriggerEnter(Collider other)
{
    if (other.CompareTag("Player"))
    {
        // pass in the expected argument
        Pickup(other);
    }
}

void Pickup(Collider player)
{
    Instantiate(pickupEffect, transform.position, transform.rotation);

    player.transform.localScale *= multiplier;

    Destroy(gameObject);
}