Python django值函数奇怪的行为?
我有5个小时的培训来解释: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的那个一刻,它还不是一个字典
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是延迟加载的,它不会执行