Django:使用values()和get_FOO_display()? [英] Django: using values() and get_FOO_display()?

查看:559
本文介绍了Django:使用values()和get_FOO_display()?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试改进一些原来需要3分钟的现有代码来准备一个大的dataTable(然后由Ajax返回)。旧的代码迭代了一个大的querySet,从各种相关对象收集信息。从我读过的内容,并从监视SQL日志,迭代查询集通常是一个坏主意,因为每个项目执行SQL。相反,我一直在使用值来在单个SQL语句中收集信息,然后再循环。使用这种技术,我将执行时间缩短到了15秒以内(我还没有完成)。但是,由于我不再使用模型对象,我无法使用,rel =noreferrer> get_FOO_display()。有没有办法在使用值()?时使用此功能?

I'm trying to improve some existing code which originally took 3 minutes to prepare a large dataTable (then returned by Ajax). The old code iterated over a large querySet, gathering information from a variety of related objects. From what I've read, and from monitoring the SQL log, iterating over querysets is generally a bad idea, because SQL is executed for each item. Instead, I've been using values to gather information in a single SQL statement, then iterating through that. Using this technique, I've reduced the execution time to under 15 seconds (and I'm still not done). However because I'm no longer using model objects, I can't use get_FOO_display(). Is there a way to use this functionality while using 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语句,那么我很乐意知道它谢谢!

Also, if there's some other way to preserve the creation of model objects yet only requires a single SQL statement on the backend, I'd love to know about it. Thanks!

推荐答案

一般来说,使用返回模型对象的基于管理器的查询可能会更好,更容易。这听起来像你原来的方法的问题并不在于你正在迭代你的查询集(如@ahmoo所说,这不是一个性能问题),但是在你的迭代循环中,你得到了更多的相关对象,需要一个或多个每个记录的附加查询。

In general, it'll probably be better and easier to use a Manager-based query that returns model objects. It sounds like the issue with your original approach is not that you were iterating over your queryset (as @ahmoo says, this isn't a performance issue), but that within your iteration loop you were getting additional related objects, requiring one or more additional queries for each record.

有几种方法可以改善仍然返回模型实例的查询的性能:

There are several ways to improve performance with queries that still return model instances:


  • 听起来最相关的是 select_related() ,这将有效地对初始查询进行表连接,以包含与外键相关的所有对象的数据。

  • It sounds like the most relevant is select_related(), which will effectively do a table join on the initial query to include data for all objects related by foreign keys.

如果不够,您还可以使用 extra() ,它允许您将子查询粘贴到SQL中。

If that's insufficient, you can also add data to your model instances with extra(), which allows you to stick subqueries into your SQL.

如果所有这些都失败,您可以执行原始SQL查询在Manager实例上使用 .raw()方法,仍然会返回模型实例。

And if all that fails, you can perform raw SQL queries using the .raw() method on a Manager instance, which will still return model instances.



    基础如果可以在SQL中以每个实例一行的方式执行此操作,那么有一种方法可以在Django中执行,并返回模型实例。

Basically, if you can do it in SQL in a way that gives you one row per instance, there's a way to do it in Django and get model instances back.

尽管如此,您可以通过Field类来获取显示名称 - 它只是丑陋:

To answer your original question, though, you can get the display name through the Field class - it's just ugly:

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

这篇关于Django:使用values()和get_FOO_display()?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆