django 在list列表中添加自定义的字段,怎么转换为QuerySet并且保留自定义的字段
时间: 2024-02-19 21:03:01 浏览: 220
你可以使用 Django 的 annotate() 方法来添加自定义的字段,然后使用 values() 方法来将结果转换为 QuerySet 并保留自定义的字段。
例如,假设你有一个模型叫做 Book,你想要添加一个字段来计算每本书的页数和价格的乘积。你可以这样做:
```python
from django.db.models import F
books = Book.objects.annotate(page_price=F('pages') * F('price')).values('title', 'page_price')
```
这个例子中,我们使用 annotate() 方法添加了一个名为 page_price 的自定义字段,该字段是 pages 和 price 字段的乘积。然后我们使用 values() 方法将结果转换为 QuerySet,并指定我们想要保留的字段(title 和 page_price)。
注意,annotate() 方法和 values() 方法都返回 QuerySet,因此你可以在它们之间使用其他的查询方法来进一步筛选和排序结果。
相关问题
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 对象合并为一个。
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 代码应该怎么修改
要将`result`转换为`QuerySet`并保留自定义字段`apply_prove`,可以使用`QuerySet`的`values()`和`annotate()`方法来实现。下面是修改后的代码:
```python
from django.db.models import Count
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并保留自定义字段apply_prove
qs = warehousePeople.objects.none()
for obj in result:
qs |= warehousePeople.objects.filter(month=obj.month, warehouse=obj.warehouse).values(*self.list_display).annotate(apply_prove=obj.apply_prove)
return qs
```
这里使用了`qs.values('month', 'warehouse').annotate(apply_prove=Count('id')).distinct()`来计算每个月、每个仓库的`apply_prove`值,并将结果存储在`item['apply_prove']`中。然后,将每个`item`转换为`warehousePeople`对象,并将`apply_prove`值存储在`obj.apply_prove`中。最后,使用`|=`操作符将每个`obj`对应的`QuerySet`合并到`qs`中,并返回`qs`。
阅读全文