Django 在实例的其他字段上使用 'when' 注释多对多字段的单个实例
Django annotate single instance of many-2-many field using 'when' on other fields of the instnce
我有一个有点复杂的模型,所以我会尽力给出一个例子来简化我的当前状态和我的需要。
我有一个查询集:
qs = MyModel.objects.all()
此查询集中的每个实例都有一个指向另一个模型的多对多字段,我们称之为 'First_M2M'。 First_M2M 有另一个模型的外键,还有另一个模型的多对多(分别为 FkModel 和 Second_M2M):
qs[0].first_m2m.fk_model.name # This is a string.
qs[0].first_m2m.second_m2m.all() # This is a many2many manager.
Second_M2M还有另外一个多对多的关系,Third_M2M:
qs[0].first_m2m.second_m2m[0].third_m2m.all() # Also a m2m manager.
现在这就是我正在尝试做的事情:我想根据 second_m2m 实例之一的值来订购我的 qs。但是,我需要选择它是哪个实例,这是通过查询 fk_model 中的一个字段(以确定 first_m2m 实例)和 [=41 中的一个实例中的一个字段来完成的=](这将决定second_m2m)。
为了让它更有趣,订购的价值是 YAML。
这是我尝试做的事情:
qs.annotate(val_to_filter_by=Case(
When(
first_m2m__fk_model__name='foo',
first_m2m__second_m2m__third_m2m__some_field='bar'),
then='first_m2m__second_m2m__value_field',
default=Value(None),
output_field=YAMLField()
)
).order_by(val_to_filter)
我相信我的错误在于查询,它不够连贯,Django 无法确定它应该采用哪个实例。但是我找不到我的问题。
任何帮助将不胜感激。
解决了...
我的“当时”有误。它是我 'Case' 而不是 'When' 的一部分。这是解决方案:
qs.annotate(val_to_filter=Case(
When(
first_m2m__fk_model__name='foo',
first_m2m__second_m2m__third_m2m__some_field='bar',
then=F('first_m2m__second_m2m__value_field')
),
default=Value(''),
output_field=YAMLField()
)).order_by(val_to_filter)
更新: 没解决...
虽然我得到了正确的查询,并且有效,但我得到了 second_m2m 的所有实例,而不是单个实例。仍然不确定如何得到我需要的东西,在这种情况下 Django 似乎不是我的朋友。
更新2:
更改了 'default=None' 并添加了
.exclude(val_to_filter=None)
就在订购之前。似乎有效...
我有一个有点复杂的模型,所以我会尽力给出一个例子来简化我的当前状态和我的需要。
我有一个查询集:
qs = MyModel.objects.all()
此查询集中的每个实例都有一个指向另一个模型的多对多字段,我们称之为 'First_M2M'。 First_M2M 有另一个模型的外键,还有另一个模型的多对多(分别为 FkModel 和 Second_M2M):
qs[0].first_m2m.fk_model.name # This is a string.
qs[0].first_m2m.second_m2m.all() # This is a many2many manager.
Second_M2M还有另外一个多对多的关系,Third_M2M:
qs[0].first_m2m.second_m2m[0].third_m2m.all() # Also a m2m manager.
现在这就是我正在尝试做的事情:我想根据 second_m2m 实例之一的值来订购我的 qs。但是,我需要选择它是哪个实例,这是通过查询 fk_model 中的一个字段(以确定 first_m2m 实例)和 [=41 中的一个实例中的一个字段来完成的=](这将决定second_m2m)。
为了让它更有趣,订购的价值是 YAML。
这是我尝试做的事情:
qs.annotate(val_to_filter_by=Case(
When(
first_m2m__fk_model__name='foo',
first_m2m__second_m2m__third_m2m__some_field='bar'),
then='first_m2m__second_m2m__value_field',
default=Value(None),
output_field=YAMLField()
)
).order_by(val_to_filter)
我相信我的错误在于查询,它不够连贯,Django 无法确定它应该采用哪个实例。但是我找不到我的问题。
任何帮助将不胜感激。
解决了...
我的“当时”有误。它是我 'Case' 而不是 'When' 的一部分。这是解决方案:
qs.annotate(val_to_filter=Case(
When(
first_m2m__fk_model__name='foo',
first_m2m__second_m2m__third_m2m__some_field='bar',
then=F('first_m2m__second_m2m__value_field')
),
default=Value(''),
output_field=YAMLField()
)).order_by(val_to_filter)
更新: 没解决...
虽然我得到了正确的查询,并且有效,但我得到了 second_m2m 的所有实例,而不是单个实例。仍然不确定如何得到我需要的东西,在这种情况下 Django 似乎不是我的朋友。
更新2: 更改了 'default=None' 并添加了
.exclude(val_to_filter=None)
就在订购之前。似乎有效...