我正在尝试改进一些现有代码,这些代码最初需要 3 分钟来准备一个大型数据表(然后由 Ajax 返回)。旧代码遍历大型查询集,从各种相关对象收集信息。从我读过的内容和监控 SQL 日志来看,迭代查询集通常不是一个好主意,因为 SQL 是针对每个项目执行的。相反,我一直在使用值在单个 SQL 语句中收集信息,然后遍历它。使用这种技术,我已将执行时间减少到 15 秒以下(我还没有完成)。但是因为我不再使用模型对象,所以我不能使用 get_FOO_display() .有没有办法在使用 values() 的同时使用此功能?
简化后,原来是:
for user in users:
data.append(user.get_name_display()) # Appends 'Joe Smith'
return data
新的代码是:
for user in users.values('name'):
data.append(user['name']) # Appends 'JSmith001', which is incorrect
return data
此外,如果有其他方法可以保留模型对象的创建但只需要在后端使用一条 SQL 语句,我很想知道。谢谢!
最佳答案
一般来说,使用返回模型对象的基于管理器的查询可能会更好也更容易。听起来你原来的方法的问题不是你在迭代你的查询集(正如@ahmoo 所说,这不是性能问题),而是在你的迭代循环中你得到了额外的相关对象,需要一个或多个每条记录的额外查询。
有几种方法可以提高仍然返回模型实例的查询的性能:
听起来最相关的是
select_related()
,这将有效地在初始查询上执行表连接,以包含通过外键关联的所有对象的数据。如果这还不够,您还可以使用
extra()
向您的模型实例添加数据。 ,它允许您将子查询粘贴到您的 SQL 中。如果所有这些都失败了,您可以执行 raw SQL queries在 Manager 实例上使用
.raw()
方法,它仍然会返回模型实例。
基本上,如果您可以在 SQL 中以每个实例一行的方式执行此操作,那么在 Django 中也有一种方法可以执行此操作并取回模型实例。
不过,要回答您最初的问题,您可以通过 Field 类获取显示名称 - 它很难看:
def get_field_display(klass, field, value):
f = klass._meta.get_field(field)
return dict(f.flatchoices).get(value, value)
# usage
get_field_display(User, 'name', 'JSmith001')
关于python - Django:使用 values() 和 get_FOO_display()?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/9674860/