Python django值函数奇怪的行为?

Python django值函数奇怪的行为?,python,django,Python,Django,我有5个小时的培训来解释:Item.objects.values('type','state')如何返回只包含两个键的字典 但是Item.objects.values('type','state').annotation(nb=Count('id'))有效 如果值函数未返回id属性,解释器如何知道该属性存在?您的模型在后台有id,并且Django ORM知道您的模型定义 Django ORM是延迟加载,在调用结果之前它不会执行任何操作。所以,在你们调用annotate的那个一刻,它还不是一个字典

我有5个小时的培训来解释:
Item.objects.values('type','state')
如何返回只包含两个键的字典

但是
Item.objects.values('type','state').annotation(nb=Count('id'))
有效


如果值函数未返回
id
属性,解释器如何知道该属性存在?

您的模型在后台有id,并且Django ORM知道您的模型定义

Django ORM是延迟加载,在调用结果之前它不会执行任何操作。所以,在你们调用annotate的那个一刻,它还不是一个字典,它仍然是一个对象。在你们请求它的结果的那个一刻,它触发对数据库的查询并返回你们的结果

Django ORM将此转换为对数据库的查询,类似于

SELECT type, state, count(id) as nb FROM items

您的模型在后台有id,Django ORM也知道您的模型定义

Django ORM是延迟加载,在调用结果之前它不会执行任何操作。所以,在你们调用annotate的那个一刻,它还不是一个字典,它仍然是一个对象。在你们请求它的结果的那个一刻,它触发对数据库的查询并返回你们的结果

Django ORM将此转换为对数据库的查询,类似于

SELECT type, state, count(id) as nb FROM items
第一个查询不返回带有两个键的字典。相反,它返回一个ValuesQuerySet;该查询集的每个元素都是一个字典

ValuesQuerySet与任何其他queryset一样,保留与模型的连接,因此可以根据需要向查询中添加任何其他元素。整个查询直到查询集被迭代后才会执行。

第一个查询不会返回带有两个键的字典。相反,它返回一个ValuesQuerySet;该查询集的每个元素都是一个字典


ValuesQuerySet与任何其他queryset一样,保留与模型的连接,因此可以根据需要向查询中添加任何其他元素。整个查询直到查询集被迭代后才会执行。

它知道
id
属性的存在,因为
Item.objects.values('type','state')
不仅仅是一个字典。它是一个对象,根据您提供的参数将自己表示为字典

假设对象是一张纸,我们称之为纸
a

id : 1
type : cheese
state : melted
当你调用它时,你实际上看到的是该对象的一种表示,它只是通过向你展示相关的部分而创建的,比如一张在
a
、纸张
B
上有孔的纸:

████████████████████
████████████████████
+--------------------+
|type: cheese        |
+--------------------+
+--------------------+
|state: melted       |
+--------------------+
但纸张
A
仍在纸张
B
下方,完好无损。这就是为什么
Item.objects.values('type','state').annotate(nb=Count('id'))
起作用的原因:当
annotate
查看对象时,它要求的是对象的实际情况,而不是外部观察者所看到的情况。换句话说,
annotate
查看纸张
A
,而不是纸张
B


通过让object
Item.objects.values('type','state')
以不同的方式代表用户和系统,它允许系统在需要检查时保留尽可能多的信息。这在ORM模型中很常见,因此数据库和数据库表示之间不会出现差异。

它知道
id
属性的存在,因为
Item.objects.values('type','state')
不仅仅是一个字典。它是一个对象,根据您提供的参数将自己表示为字典

假设对象是一张纸,我们称之为纸
a

id : 1
type : cheese
state : melted
当你调用它时,你实际上看到的是该对象的一种表示,它只是通过向你展示相关的部分而创建的,比如一张在
a
、纸张
B
上有孔的纸:

████████████████████
████████████████████
+--------------------+
|type: cheese        |
+--------------------+
+--------------------+
|state: melted       |
+--------------------+
但纸张
A
仍在纸张
B
下方,完好无损。这就是为什么
Item.objects.values('type','state').annotate(nb=Count('id'))
起作用的原因:当
annotate
查看对象时,它要求的是对象的实际情况,而不是外部观察者所看到的情况。换句话说,
annotate
查看纸张
A
,而不是纸张
B


通过让object
Item.objects.values('type','state')
以不同的方式代表用户和系统,它允许系统在需要检查时保留尽可能多的信息。这在ORM模型中很常见,因此数据库和数据库表示之间不会出现差异。

如果不指定“id”字段,我看不出有任何问题,它只返回您指定的字段,除非忽略字段参数。请查看中的
ValuesIterable
class,并检查中的最后一个示例。关于上一个问题,您似乎试图将
values
用于不同的目的。如果您不指定“id”字段,我看不出有任何问题,它只返回您指定的字段,除非您忽略字段参数。请查看中的
ValuesIterable
类,并检查中的最后一个示例。关于你的最后一个问题,你似乎试图用
值来达到不同的目的。我的问题很简单。如果annotate是从一个没有“id”的字典调用的,它怎么知道“id”的存在呢it@user2080105您的模型在后台有id,并且Django ORM知道您的模型定义Django ORM是延迟加载的,在调用结果之前它不会执行任何操作。所以,在你们们调用annotate的那个一刻,它还不是一本词典,它仍然是一本词典。我的问题很简单。如果annotate是从一个没有“id”的字典调用的,它怎么知道“id”的存在呢it@user2080105您的模型在后台有id,而且Django ORM知道您的模型定义Django ORM是延迟加载的,它不会执行