def get_queryset(self, request): qs = warehousePeople.objects.all() if 'name' in request.GET and request.GET['name'] != 'none': # 条件查询 qs = qs.filter(name=request.GET['name']) qs1 = qs.none() 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') for obj in qs: if qs1.filter(month=obj.month, warehouse=obj.warehouse.id).exists(): break else: infoLi = qs.filter(month=obj.month, warehouse=obj.warehouse.id) first_obj = infoLi.first() infoLiOne = qs.filter(pk=first_obj.pk) qs1 |= infoLiOne else: if 'subjectMatter' not in self.list_display: self.list_display.append('subjectMatter') if "apply_prove" in self.list_display: self.list_display.remove('apply_prove') if 'name' in request.GET and request.GET['name'] != 'none': return qs1 else: return qs 代码中如何使用annotate方法动态的为qs1添加动态字段apply_prove?
时间: 2024-02-10 17:08:17 浏览: 164
可以使用annotate方法来为qs1添加动态字段apply_prove,具体代码如下:
```
from django.db.models import Case, When, IntegerField
qs1 = qs.none().annotate(
apply_prove=Case(
When(warehouse__isnull=True, then=0),
When(month__isnull=True, then=0),
default=1,
output_field=IntegerField(),
)
)
```
这段代码中,我们使用了annotate方法来为qs1添加一个名为apply_prove的动态字段。annotate方法可以接收多个参数,每个参数都是一个表达式,用来为查询集中每个对象添加一个字段。在这个例子中,我们使用了Case表达式来根据warehouse和month是否为空来计算apply_prove的值。具体来说,当warehouse或month为空时,apply_prove的值就为0,否则就为1。最后,我们指定了这个动态字段的输出类型为IntegerField。
相关问题
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 对象合并为一个。
class GroupAdmin(admin.ModelAdmin): search_fields = ('name',) ordering = ('name',) filter_horizontal = ('permissions',) def formfield_for_manytomany(self, db_field, request=None, **kwargs): if db_field.name == 'permissions': qs = kwargs.get('queryset', db_field.remote_field.model.objects) # Avoid a major performance hit resolving permission names which # triggers a content_type load: kwargs['queryset'] = qs.select_related('content_type') return super().formfield_for_manytomany(db_field, request=request, **kwargs)
这段代码是用来定义 Django 管理后台中的一个名为 Group 的模型的管理类。其中:
- `search_fields = ('name',)` 表示在管理后台的列表页中添加一个搜索框,可以搜索该模型的 name 字段。
- `ordering = ('name',)` 表示在管理后台的列表页中按照 name 字段进行排序。
- `filter_horizontal = ('permissions',)` 表示在管理后台的编辑页中使用水平的多选框来选择 permissions 字段的值。
另外,`formfield_for_manytomany` 方法是一个钩子方法,用来为多对多关系字段定制表单字段。在这里,它判断如果是 permissions 字段,则通过 `select_related` 方法预先加载 content_type 字段,以避免性能问题。最后,调用父类的方法来创建表单字段。
阅读全文