【问题标题】:Django retrieve data from two tablesDjango 从两个表中检索数据
【发布时间】:2018-10-03 20:44:50
【问题描述】:

我有以下型号:

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

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

谢谢

【问题讨论】:

  • 你看过这篇文章吗? stackoverflow.com/questions/4125379/…
  • 感谢您的快速回复!我已经阅读了这篇文章以及互联网上的所有其他文章,甚至是文档,但不知道我做错了什么,它没有从两个表中选择数据。它只从 Purchased_Items 中选择!我正在使用 Django 版本 2。

标签: python sql django


【解决方案1】:

Re:选择相关

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

例子:

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

这意味着在 ORM 中默认允许“join”操作。使用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 自动为ForeignKey 关系创建带有_id 后缀的字段名称。这个想法是对象可以直接作为item.p 访问,并且数据库字段键设置为p_id。这可以帮助您检索purchase 对象

【讨论】:

  • 我运行 items = Purchased_Items.objects.filter().select_related('Purchases')[:100] 然后 for i in items: print(i.Purchases),但我收到此错误:django.core.exceptions.FieldError:select_related 中给出的字段名称无效:'Purchases'。选择是:p_id
  • 更新了代码,用作p_id的属性。另外,请阅读 django 模型命名约定。复数一般不用于模型名称,除了 m2m 字段。
  • 通过运行 items = Purchased_Items.objects.filter().select_related('p_id') 我得到 Purchased_Items 字段但没有得到 Purchases 字段。但是,当运行 print Purchased_Items.objects.filter().select_related('p_id').query 并将输出粘贴到 mysql 终端时,没有任何问题。还是不知道怎么办!
  • 您如何访问购买字段。请分享代码
  • 在我看来:items = Purchased_Items.objects.select_related('p_id') context = { 'items': items, } in the template: {% for i in items %} {{forloop.counter}}. {{ i.date }} {{ i.total }} {% endfor % }
猜你喜欢
  • 1970-01-01
  • 2020-07-28
  • 2013-03-26
  • 1970-01-01
  • 2023-04-04
  • 2012-12-09
  • 2013-07-23
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多