Django从两个表中检索数据

时间:2018-04-23 17:59:19

标签: python sql django

我有以下型号:

class Purchases(models.Model):
    p_id = models.IntegerField(primary_key=True, default=0)
    date = models.DateField(default=datetime.now)

    def __str__(self):
        return self.date.strftime('%Y-%m-%d')

    class Meta:
        verbose_name_plural = "Purchases"


class Purchased_Items(models.Model):
    p_id = models.ForeignKey(Purchases, on_delete=models.CASCADE)
    item = models.CharField(max_length=80)
    size = models.IntegerField(max_length=2)
    quantity = models.IntegerField(max_length=3)
    price = models.IntegerField(max_length=4)
    total = models.IntegerField(default=0)

    def __str__(self):
        return self.item

    class Meta:
        verbose_name_plural = "Purchased Items"

我正在尝试使用内部联接检索:

pur = Purchased_Items.objects.all().select_related()

但我没有得到所需的结果。基本上我想要以下sql:

select * from finance_purchases as fp
     inner join finance_purchased_items pi 
           ON (fp.p_id = pi.p_id_id);

另一个问题是,虽然Purchased_Items中的外键是p_id但是在sql表的列中是p_id_id!为什么?它背后的逻辑是什么?

由于

1 个答案:

答案 0 :(得分:1)

Re:选择相关

Django ORM允许您使用简单的属性引用直接从Purchases对象访问Purhcased_Items对象。

示例:

item = Purchased_Items.objects.get(pk=123)  # This is the `Purchase_Items` instance
purchase = item.p_id  # This is the `Purchases` instance

这意味着"加入" ORM中默认允许操作。使用select_related的原因是当您执行此外键引用时,Django每次都会触发一个离散查询。所以如果你的代码看起来像这样:

items = Purchased_Items.objects.filter()[:100]  # This fires 1 sql query
for i in items:
    print i.purchase  # This line fires 1 SQL query

然后总共触发了101个SQL查询。这也称为 N + 1选择查询问题 1

如果将行更改为:

,则可以避免这种情况
items = Purchased_Items.objects.filter().select_related('p_id')[:100]  # This fires just 1 sql query for the entire operation
for i in items:
    print i.purchase  # No query fired, data is already selected in Join

您可以通过在django

中打印查询来查看差异
print Purchased_Items.objects.filter().query
print Purchased_Items.objects.filter().select_related('p_id').query

回复:p_id_id

Django ORM自动创建_id后缀为ForeignKey关系的字段名称。我们的想法是,对象可以直接作为item.p访问,数据库字段键可以设置为p_id。这有助于您检索purchase对象