【问题标题】:Django select all models with foreign keyDjango选择所有具有外键的模型
【发布时间】:2015-09-19 06:44:36
【问题描述】:

在一个 Django Web 应用程序中,我定义了一个名为 Server 的模型

class Server(models.model):

以及一堆使用这个模型作为外键的模型

class ServerInfo(models.Model):
    server = models.ForeignKey(server, null=True)
class ServerDNSRecord(models.Model):
    server = models.ForeignKey(server, null=True)
...etc

现在我有一个 API 调用,它返回一个服务器及其所有附加信息。目前,我只是为每个服务器执行一个 for 循环,并使用服务器名称搜索每个信息表。问题是有时我需要进行一个返回所有服务器及其信息的 API 调用。

这会为数据库创建大量的 SQL 查询,并且此调用的响应时间通常大于 5 秒,这是不可接受的。

是否有任何简单的方法来进行某种联接或外键搜索以减少数据库调用量以加快处理速度?

【问题讨论】:

标签: python sql django postgresql


【解决方案1】:

您想要的是对您将要抓取的所有相关类型执行 select_related 。例如:

res = Server.objects.prefetch_related("serverinfo_set", "serverdnsrecord_set", ...).first()
res.serverinfo_set # Won't need another query
res.serverdnsrecord_set # Won't need another query

此外,如果您想自动执行此操作,您可以这样做:

related_fieldnames = [f.get_accessor_name() for f in Server._meta.get_all_related_objects()]
res = Server.objects.prefetch_related(*related_fieldnames).first()
res.serverinfo_set # Won't need another query
res.serverdnsrecord_set # Won't need another query

我应该指出,如果这个应用程序被重用并且有人开始向服务器添加更多外键,那么这些当然都会得到 select_related。

【讨论】:

  • 我很困惑,因为在 django 文档中,似乎 select_related 用于与我想做的相反的事情。也就是说,您使用外键选择与模型相关的模型,它会找到模型表。我还收到一条错误消息,指出 Query_Set 没有属性 find_one 所以我认为这不是一个有效的方法。
  • @Josh Whoops,意思是 first() 而不是 find_one(),mongodb 太多了。
  • 另外,您对文档的评论是准确的,这有点令人困惑。但是 iirc select_related 只是使用您在 . 之后用于访问数据的相同名称进行操作,并在之后使用 . 的任何地方使用 __(例如 res.serverinfo_set.someother_foreign_key 将是 serverinfo_set__someother_foreign_key
  • 所以在我的服务器模型中,我有一个对数据中心的外键引用。我在使用我的 select_related 时遇到错误,说数据中心是唯一可用的选项。
  • @Josh 嗯,你是对的。显然这就是 prefetch_related 的用途。不知道他们是否改变了这一点,或者我只是不知道。
猜你喜欢
  • 1970-01-01
  • 2021-09-03
  • 1970-01-01
  • 1970-01-01
  • 2017-06-03
  • 2012-03-16
  • 1970-01-01
  • 2020-12-18
  • 1970-01-01
相关资源
最近更新 更多