如何将qs = qs.values('month', 'warehouse').annotate(apply_prove=Count('id')).distinct()中的字典转换为模型对象
时间: 2023-11-28 13:04:26 浏览: 157
假设您有一个名为WarehouseApply的模型,您可以使用以下代码将qs中的字典转换为WarehouseApply模型对象:
```
from django.db.models import Count
qs = qs.values('month', 'warehouse').annotate(apply_prove=Count('id')).distinct()
warehouse_apply_list = []
for item in qs:
warehouse_apply = WarehouseApply(
month=item['month'],
warehouse=item['warehouse'],
apply_prove=item['apply_prove']
)
warehouse_apply_list.append(warehouse_apply)
WarehouseApply.objects.bulk_create(warehouse_apply_list)
```
在上面的代码中,我们首先使用values()和annotate()方法获取一个字典列表。然后,我们遍历字典列表并创建WarehouseApply模型对象。最后,我们使用bulk_create()方法将WarehouseApply模型对象列表批量插入到数据库中。注意,bulk_create()方法可以大幅提高插入效率。
相关问题
def get_queryset(self, request): qs = super().get_queryset(request) result = [] if 'name' in request.GET and request.GET['name'] != 'none': # 条件查询 qs = warehousePeople.objects.filter(name=request.GET['name']) if 'subjectMatter' in self.list_display: self.list_display.remove('subjectMatter') if 'apply_prove' not in self.list_display: self.list_display.append('apply_prove') qs = qs.values('month', 'warehouse').annotate(apply_prove=Count('id')).distinct() for item in qs: warehouse = warehouseInformation.objects.get(id=item['warehouse']) obj = warehousePeople(month=item['month'], warehouse=warehouse) obj.apply_prove = item['apply_prove'] result.append(obj) 怎么将result转换为QuerySet,并且保留result列表中自定义字段apply_prove
你可以使用 Django 的 QuerySet.values() 方法来构造一个新的 QuerySet 对象,同时保留自定义字段 apply_prove。具体实现如下:
```python
from django.db.models import IntegerField, CharField, Value
from django.db.models.functions import Cast
# 将自定义字段 apply_prove 转换为整型,并加入到 QuerySet 中
result_qs = warehousePeople.objects.annotate(
apply_prove=Cast(Value(0), output_field=IntegerField())
).values(
'month',
'warehouse_id',
'apply_prove',
)
# 遍历 result 列表,将数据填充到 QuerySet 中
for item in result:
result_qs = result_qs | warehousePeople.objects.filter(
month=item.month,
warehouse=item.warehouse,
).annotate(
apply_prove=Value(item.apply_prove, output_field=IntegerField())
).values(
'month',
'warehouse_id',
'apply_prove',
)
```
这样,result_qs 就是一个 QuerySet 对象,包含了 result 列表中的所有数据,并保留了自定义字段 apply_prove。请注意,由于 QuerySet.values() 方法返回的是一个新的 QuerySet 对象,因此需要使用“OR”操作符(“|”)将多个 QuerySet 对象合并为一个。
ww = qs.filter(month=num.month, warehouse=num.warehouse.id).annotate( apply_prove=Count('id')) 为什么查询到3条记录,apply_provesss还是1呢,怎么修改才是3,并且www queryset中的还是object而不是字典
根据你提供的代码,假设qs是一个QuerySet对象,那么这段代码的作用是查询month等于num.month,warehouse等于num.warehouse.id的记录,并统计每条记录中id的个数,存储在apply_prove中。
根据你的描述,查询到了3条记录,但是apply_prove为1,这种情况可能是由于Count方法没有按照你的预期进行分组操作,而是将所有记录的id个数汇总计算为1,导致apply_prove的值都为1。
可以尝试将annotate方法中的参数改为:apply_prove=Count('id', distinct=True),这样Count方法就会按照不同的记录进行分组计算,得到正确的apply_prove值。修改后的代码如下:
```
ww = qs.filter(month=num.month, warehouse=num.warehouse.id).annotate(apply_prove=Count('id', distinct=True))
```
另外,你提到ww queryset中的还是object而不是字典,这是因为annotate方法生成的QuerySet对象是Model对象而不是字典,可以通过在annotate方法中添加参数将结果转化为字典形式。修改后的代码如下:
```
ww = qs.filter(month=num.month, warehouse=num.warehouse.id).annotate(apply_prove=Count('id', distinct=True)).values('month', 'warehouse', 'apply_prove')
```
这样就可以得到一个字典形式的QuerySet对象了。
阅读全文