【问题标题】:Django: How to write a GET query, using values_list attribute?Django:如何使用 values_list 属性编写 GET 查询?
【发布时间】:2013-02-02 01:50:24
【问题描述】:

我想查询单个实例的模型(例如,id=1),但我只想返回单个字段的值('title')。我可以通过以下查询来实现这一点:

SomeModel.objects.filter(pk=1).values_list('title', flat=True)

但是getfilter 更有效。但是,values_listvalues 不适用于 get 查询。理想情况下,我更愿意这样做:

SomeModel.objects.get(pk=1).values_list('title', flat=True)

但我收到以下错误:AttributeError: SomeModel has no attribute 'title'

编写此查询的最佳方式是什么?

【问题讨论】:

  • 您可能不必担心filterget 之间的性能。真正重要的是您不执行 1+N 查询。您当前的代码几乎看起来像您正在为各种键执行此查询。如果是这种情况,您应该执行连接或使用pk__in=[1,2,3,4,5] 同时获取多个对象的标题。
  • 另外 OP 也不需要担心filterget 之间的性能差异,因为没有任何 ;)
  • 除非,我想,OP 正在尝试处理多行......在这种情况下,get 更快,因为它会立即抛出异常!跨度>

标签: python django django-models django-queryset


【解决方案1】:

但是getfilter 更有效。

这根本不是真的。 .get(…) 将生成完全相同.filter(…) 相同的 SQL。

使用:

SomeModel.objects.filter(pk=1)[0:1].values_list('title', flat=True)

会做你想做的事,并且将具有与.get(…) 完全相同的性能特征(实际上,它会快一点,因为.get(…) 会检查是否会返回多行...): 在 [4] 中:导入日志记录 在 [5] 中: l = logging.getLogger("django.db") 在 [6] 中:l.setLevel(logging.DEBUG) 在 [7] 中:User.objects.filter(id=1)[0:1].values_list() DEBUG:django.db.backends:(0.006) SELECT "auth_user"."id", "auth_user"."username", "auth_user"."first_name", "auth_user"."last_name", "auth_user"."email ", "auth_user"."password", "auth_user"."is_staff", "auth_user"."is_active", "auth_user"."is_superuser", "auth_user"."last_login", "auth_user"."date_joined" FROM "auth_user" WHERE "auth_user"."id" = 1 LIMIT 1;参数=(1,) Out[7]: [(1, u'admin', u'Admin', u'User', u'admin@example.com', u'sha1$bf3bc$daa1fb58a8a41e15c730ae86bc0faf4c01fdd3a1', True, True, True, datetime. datetime(2013, 1, 8, 21, 15, 51, 855527), datetime.datetime(2012, 1, 10, 15, 13, 55))] 在 [8] 中:User.objects.get(id=1) DEBUG:django.db.backends:(0.001) SELECT "auth_user"."id", "auth_user"."username", "auth_user"."first_name", "auth_user"."last_name", "auth_user"."email ", "auth_user"."password", "auth_user"."is_staff", "auth_user"."is_active", "auth_user"."is_superuser", "auth_user"."last_login", "auth_user"."date_joined" FROM "auth_user" WHERE "auth_user"."id" = 1 ;参数=(1,) 出[8]:

【讨论】:

  • Django 肯定不会使用LIMIT 代替get。否则它永远不会抛出MultipleObjectsReturnedLIMIT 2 是一种选择,但由于您希望只返回一个元素,这只会降低查询的性能。
猜你喜欢
  • 1970-01-01
  • 2017-07-22
  • 1970-01-01
  • 2020-04-03
  • 2014-03-21
  • 2020-10-10
  • 2016-12-01
  • 2018-02-27
  • 2013-12-26
相关资源
最近更新 更多