【问题标题】:Django select field with thousands of choices creating thousands of database queries具有数千个选择的 Django 选择字段创建数千个数据库查询
【发布时间】:2017-06-06 14:18:38
【问题描述】:

我有两个模型,模型 B 和模型 C,它们都扩展了模型 A。

在一个表单中,我有一个模型 A 的模型选择字段 - 这显然会加载模型 B 和 C 的所有实例,这是我的意图。

所以这个下拉列表超过 1000 个“A 对象”。我正在使用 hasattr() 来确定它们是 B 还是 C,然后使用这些类中的 unicode 方法从下拉列表中以字符串形式显示对象。

这会创建数千个 SQL 查询,大约需要一分钟的时间来处理。现在我的解决方案是查询数据库 3 次(获取所有 A、B 和 C 对象,然后遍历 A 并确定每个对象是 B 类型还是 C 类型,并将正确的 unicode 字符串推送到使用的列表中在下拉列表中。然后我清理数据并在保存表单时选择正确的对象。这是 hackey(对我来说)。

我想知道当该模型是其他模型的基本模型时,是否有人知道使用数千个模型对象选择填充下拉列表的有效方法。

干杯, 院长

【问题讨论】:

  • unicode 方法到底是做什么的?它们不应该引起额外的查询
  • B 或 C 的对象对其他模型具有外键字段。 - unicode 从这些其他模型中获取一个字段(self.foreign_key_field.field_to_print_out)。例如,单个对象是 B 类型(扩展 A),我想从 Model X 中打印出一个最能代表该对象的字段(并通过外键关联)。 select_related() 会在这里发挥作用吗? (ps。我是 Django 新手)
  • 那是正确的,我已经重写了我的答案(因为原件是在一个漫长的星期六晚上写的并且完全不正确......)希望能解释 1k 查询的来源

标签: python sql django


【解决方案1】:

unicode 从这些其他模型中获取一个字段 (self.foreign_key_field.field_to_print_out)。

这是进行其他查询的地方,而不是来自对 unicode 的调用或检查它是 a b 还是 a c。

如果您的 unicode 方法仅引用本地字段,这不会是一个问题,但正如您所注意到的,需要连接的字段不会自动完成以节省一些甚至可能不需要的事情的性能。

如果你使用 django-debug-toolbar,你应该注意到这 1000 个查询是对相关对象的检索,而不是对象列表。

所以是的,正如您所指出的,select_related 在这里会有所帮助,因为这是您告诉 django 您确实需要这些字段。

【讨论】:

  • 不幸的是,1k+ 项是必需的。用户需要能够访问全国范围内的值集合。我正在为 select2 使用 django 库来管理它的 UI 透视图。你能解释一下 .annotate 是如何在这里工作的吗?我想不通(我对复杂查询没有太多经验)
  • 难道这仍然会为每个对象命中数据库一次吗?这仍然是对数据库的上千个查询......
  • 再次,我不太确定注释是如何工作的......但据我所知,如果 my_queryset 是“A.objects.all()”,所有这些注释都会提供一种查看它是 b 型还是 c 型的方法。如何在单个查询中获取 A 类型的所有对象及其 unicode_ 表示形式?
  • 通过使用 select_related('tablename', 'tablename__foreignkey') 得到这个工作。双下划线可更深入地研究关系并防止数以千计的查询。
  • @DeanSherwin - 有趣,select_related('foreign_key') 不起作用吗?我不确定我是否正确误解了您的用法,并认为我在某处读到了有关 select_related 对不存在字段的参数的更多信息。不管怎样,很高兴它成功了,对之前的 foobar 答案感到抱歉!
猜你喜欢
  • 2020-08-29
  • 1970-01-01
  • 2013-03-03
  • 1970-01-01
  • 1970-01-01
  • 2018-06-20
  • 2018-05-06
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多