官方文档:https://docs.djangoproject.com/en/1.3/ref/models/querysets/#values
1. values(*fields)
这个方法返回的是ValuesQuerySet,是QuerySet 的子类,也就是说,你可以用QuerySet里的方法。 需要注意的是,返回的不是list,不要直接当list来用了。对ValuesQuerySet遍历,每一个元素是“字典”dict。
当不传入参数时,返回这个model的所有字段
AppDef.objects.values()
[{'creator': u'admin', 'apptype_name': u'uc3g', 'apptype_chn_name': u'3G\u95e8\u6237', 'note': u'', ...},...]
当传入参数时,只会列出你指定的参数
AppDef.objects.values('apptype_name')
[{'apptype_name': u'uc3g'},...]
也可以加上filter,filter在前或者后面都是一样的
AppDef.objects.filter(pk=1).values('apptype_name')
AppDef.objects.values('apptype_name').filter(pk=1)
如果想把关联的字段也一起查出来
OneToOneField, ForeignKey 和ManyToManyField 关系的都可以。
ManyToManyField 在Django1.3版后才支持
LogTypeDef定义了一个app的ForeignKey
LogTypeDef.objects.filter(pk=6).values('pk', 'app__apptype_name')
[{'pk': 6L, 'app__apptype_name': u'wapsearch'}]
如果你只想拿到app_id,可以这样
下面三种方法都是一样的,只是返回的结果名字对应你的查询语句
LogTypeDef.objects.filter(pk=6).values('pk', 'app_id')
LogTypeDef.objects.filter(pk=6).values('pk', 'app')
LogTypeDef.objects.filter(pk=6).values('pk', 'app__id')
注意在关联关系为多对多的时候,它只会帮你一条一条的列出来,而不会帮你合并为一个list。
例如会返回类型的结果:同一个pk并不会帮你合并app_id
[{pk: 6, app_id: 2}, {pk: 6, app_id: 3}]
2. 注意事项
当同时使用distinct()和values(),需要注意order_by() (或者默认 model ordering) ,会自动加入select 中作为distinct项,所以返回的结果你以为是重复的,其实是order by的字段没列出来。
如果在extra() 之后用values(),一定要把extra用到的字段也加进来;如果extra()在values()之后,extra的字段会自动加进select。
Because ManyToManyField attributes and reverse relations can have multiple related rows, including these can have a multiplier effect on the size of your result set. This will be especially pronounced if you include multiple such fields in your values() query, in which case all possible combinations will be returned. (这个不太懂什么意思,应该是当values有多个manytomanyfield的时候,会尽量合并一些)
3. 适用范围
l 只需要返回dict,而不需要返回model object。
l 只需要返回简单的数据(包括层次简单)
4. Values_list
和values一样,只是返回的不是字典而是元组。