django values(*field) values_list() 使用

本文详细介绍了Django中QuerySet的使用方法,包括values和values_list的使用技巧及注意事项,帮助读者更好地理解和运用这些功能。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

这个方法返回的是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'},...]

也可以加上filterfilter在前或者后面都是一样的

AppDef.objects.filter(pk=1).values('apptype_name') AppDef.objects.values('apptype_name').filter(pk=1)

如果想把关联的字段也一起查出来OneToOneField, ForeignKey 和ManyToManyField 关系的都可以。
ManyToManyField 在Django1.3版本后才支持   LogTypeDef定义了一个appForeignKey

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。

3. Values_list

values一样,只是默认返回的不是字典而是元组;可以增加flat=True参数,返回某个字段的列表,例子如下:

Case_images.objects.filter(case=case_id).order_by('-created_time').values_list('url',flat=True)

 

转载于:https://my.oschina.net/u/2371517/blog/516858

我创建了一个django drf项目,里面封装了一些函数,和规范,函数是class SearchableListModelMixinUp(viewsets.ModelViewSet): time_range_fields = [] def list(self, request, *args, **kwargs): query_params = request.query_params serializer_fields = set(self.get_serializer().fields.keys()) query = Q() # 普通字段模糊搜索(排除时间范围字段) for field, value in query_params.items(): if field in serializer_fields and field not in self.time_range_fields and value: query.add(Q(**{f'{field}__icontains': value}), Q.AND) # 时间范围过滤 for time_field in self.time_range_fields: time_values = query_params.getlist(f'{time_field}[]') if time_values and len(time_values) == 2: start_date = parse_datetime(time_values[0]) end_date = parse_datetime(time_values[1]) if start_date and end_date: start_date = make_aware(start_date) end_date = make_aware(end_date) query.add(Q(**{f'{time_field}__range': (start_date, end_date)}), Q.AND) # 查询和排序 queryset = self.get_queryset().filter(query).order_by('id') # 默认按 ID 排序 page = self.paginate_queryset(queryset) if page is not None: serializer = self.get_serializer(page, many=True) return self.get_paginated_response(serializer.data) serializer = self.get_serializer(queryset, many=True) return Response(serializer.data, status=status.HTTP_200_OK) 创建接口规范是class PermissionViewSet(viewsets.ModelViewSet): queryset = Permission.objects.all() serializer_class = PermissionSerializer pagination_class = None # 禁用分页器 # permission_classes = [permissions.IsAdminUser] 或者class UserMenuView(APIView): authentication_classes = [JWTAuthentication] permission_classes = [IsAuthenticated] def get(self, request): user = request.user # 获取用户的角色 roles = UserRole.objects.filter(user=user).values_list('role', flat=True) # 获取用户的角色名称 roles_names = UserRole.objects.filter(user=user).select_related('role').values_list('role__name', flat=True) # 将查询结果转换为列表 roles_list = list(roles_names) # 获取这些角色对应的权限 permissions = RolePermission.objects.filter(role__in=roles).values( 'permission__id', 'permission__name', 'permission__codename', 'permission__parent_id', 'role__name' # 添加 parent_id ).distinct() return Response({ 'roles': roles_list, 'menu': list(permissions) }) 写个规范文档
03-13
### Django 中 `value_list` 方法的使用说明 #### 什么是 `value_list`? 在 Django ORM 中,`value_list()` 是一种用于查询特定字段值的方法。它返回的是一个列表 (Pythonlist),其中每个元素是一个元组或者单个值,具体取决于参数设置。这种方法非常适合当你只需要获取某些字段的数据而不需要完整的对象实例时。 此方法可以接受两个可选参数: 1. **fields**: 要提取的具体字段名称。 2. **flat**: 如果只请求了一个字段,则可以通过将 flat 设置为 True 来简化结果结构,使其成为一个一维列表而不是嵌套的一层元组[^1]。 #### 基本语法 ```python queryset.value_list(*fields, flat=False) ``` - *fields*: 字段名作为位置参数传入。 - flat: 当指定单一字段并希望得到平面化(即不带额外括号包裹)的结果集合时设为True;仅当 fields 参数只有一个时有效[^3]。 #### 示例代码展示 假设有如下定义的商品模型: ```python from django.db import models class Product(models.Model): name = models.CharField(max_length=100) price = models.DecimalField(max_digits=10, decimal_places=2) stock = models.IntegerField() def __str__(self): return self.name ``` 以下是几种常见的用法示例: ##### 获取多个字段组成的元组列表 如果想获得产品表中的价格(price)和库存(stock)两列数据构成的一个二维数组形式的结果集: ```python result = Product.objects.all().values_list('price', 'stock') print(result) # 输出可能像这样 [(9.99, 5), (19.99, 10)] ``` 上述命令会生成类似于下面这样的 Python 列表[(...)],每项都是由所选取各字段对应值组合而成的 tuple[]. ##### 单独获取某一列形成简单列表 当我们只需知道所有产品的名字(name)而不关心其他属性的时候,可以用到'flat=True': ```python names_only = Product.objects.all().values_list('name', flat=True) print(names_only) # 可能输出 ['Product A', 'Product B'] ``` 这里因为设置了 flat=True 并且仅仅选择了'name'这唯一一项,所以最终得到了不含任何多余层次关系的标准 python lists[],而非 tuples()内的lists[]. 注意:如果你尝试在一个多于一个 field 上应用 flat=True 将抛出异常 ValueError ["Cannot use 'flat' when values_list is called with more than one field."] [^4]. #### 总结 通过上面的例子可以看出,value_lists 提供了一种简洁高效的方式来处理数据库记录投影操作——允许开发者快速定位关注的部分信息点,减少不必要的内存占用同时也加快了程序运行效率. ---
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值