python - Django:使用 values() 和 get_FOO_display()?

标签 python django django-queryset

我正在尝试改进一些现有代码,这些代码最初需要 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/

相关文章:

python - 在 Django 中查找相关字段的优雅方式

Python setup.py 安装抛出 zipimport.ZipImportError

python - 第一个 if 条件有效,但 elif 条件无效

python - 检查python中命令行参数的数量

django - 如何将过滤器关键字上的字符串传递给 Django 对象模型?

django-django-taggit表单

python - 无法使用提供的凭据登录

django - 如何在 values_list 查询中使用 Django GenericRelation

python - Django 组合可变数量的查询集

python - MySql Python 连接