ChatGPT解决这个技术问题 Extra ChatGPT

在Django中,以下两者有什么区别:

Article.objects.values_list('comment_id', flat=True).distinct()

VS

Article.objects.values('comment_id').distinct()

我的目标是获取每个 Article 下的唯一评论 ID 列表。我已经阅读了文档(实际上已经使用了这两种方法)。结果显然相似。

使用 values_list 您可以在使用访问字典所需的值时执行 if self.id in Article.objects.values_list('comment_id', flat=True):
@dnaranjo - 你可以,但为什么不直接做 Article.objects.filter(comment_id=self.id).exists()
这是另一个问题的答案

A
Alasdair

values() 方法返回一个包含字典的 QuerySet:

<QuerySet [{'comment_id': 1}, {'comment_id': 2}]>

values_list() 方法返回一个包含元组的 QuerySet:

<QuerySet [(1,), (2,)]>

如果您将 values_list() 与单个字段一起使用,则可以使用 flat=True 返回单个值而不是 1 元组的 QuerySet:

<QuerySet [1, 2]>

哦,两者之间没有区别 distinct() 是如何使用的吧?
不,我认为 distinct() 的工作方式没有任何不同。重要的是您要使用哪种数据结构。
values() 返回 QuerySet 而不是 list。虽然 values() 返回的对象看起来像一个 list,但在某些情况下它的行为并不像一个。例如,除非我们将其转换为“列表”,否则它不会是 json 可序列化的
@AbhijitGhate 好点,我已经更新了答案以使其更清楚。
只需使用 list 函数,您就可以轻松地将 values_list 的返回值转换为真正的 Python 列表:list(Article.objects.values_list('comment_id', flat=True).distinct())
F
Flimm

值()

当用作可迭代对象时,返回返回 dictionaries 而不是模型实例的 QuerySet。

值列表()

当用作可迭代对象时,返回返回 list of tuples 而不是模型实例的 QuerySet。

清楚的()

distinct 用于 eliminate the duplicate 元素。

例子:

>>> list(Article.objects.values_list('id', flat=True)) # flat=True will remove the tuples and return the list   
[1, 2, 3, 4, 5, 6]

>>> list(Article.objects.values('id'))
[{'id':1}, {'id':2}, {'id':3}, {'id':4}, {'id':5}, {'id':6}]

所以它是在 values 的情况下返回的字典列表
澄清一下:distinct() 消除了查询结果中的重复元素,而不是数据库中的重复元素。
g
glennsl

您可以通过以下方式获得不同的值:

set(Article.objects.values_list('comment_id', flat=True))

这将比使用 distinct() 在数据库级别消除重复要慢得多。
此外,使用 set() 将强制对整个表进行查询,此时 QuerySet(由 distinct() 返回)将仅在需要时流式传输数据。
K
Kai - Kazuya Ito

“values()”返回字典的 QuerySet。

例如:

print(User.objects.all().values()) # Return all fields
# <QuerySet [{'id': 1, 'name': 'John'}, {'id': 2, 'name': 'Tom'}]>

print(User.objects.all().values("name")) # Return "name" field
# <QuerySet [{'name': 'John'}, {'name': 'Tom'}]>

“values_list()”返回元组的 QuerySet。

例如:

print(User.objects.all().values_list()) # Return all fields
# <QuerySet [(1, 'John'), (2, 'Tom')]>

print(User.objects.all().values_list("name")) # Return "name" field
# <QuerySet [('John',), ('Tom',)]>

带有“flat=True”的“values_list()”返回值的 QuerySet。 * 否或允许有“flat=True”的一个字段,并且一个字段必须是第一个参数,“flat=True”必须是第二个参数。

例如:

print(User.objects.all().values_list(flat=True)) # Return "id" field
# <QuerySet [1, 2]>

print(User.objects.all().values_list("name", flat=True)) # Return "name" field
# <QuerySet ['John', 'Tom']>

print(User.objects.all().values_list(flat=True, "name")) # Error

print(User.objects.all().values_list("id", "name", flat=True)) # Error

r
run_the_race

了解差异的最佳位置是 official documentation on values / values_list。它有很多有用的例子并且解释得非常清楚。 django 文档非常用户友好。

这是一个简短的片段,可以让 SO 评论者满意:

价值观

当用作可迭代对象时,返回一个返回字典而不是模型实例的 QuerySet。

并阅读其后面的部分:

价值清单

这类似于 values() ,只是它不是返回字典,而是在迭代时返回元组。