0

我有一个有点复杂的模型,所以我会尽力给出一个简化我当前状态和需求的例子。

我有一个查询集:

qs = MyModel.objects.all()

此查询集中的每个实例都有一个指向另一个模型的多对多字段,我们称之为“First_M2M”。First_M2M 对另一个模型有一个外键,对另一个模型(分别为 FkModel 和 Second_M2M)有一个多 2 多:

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 实例)和第三个_m2m 中的一个实例中的一个字段来完成的(这将确定 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 来说不够连贯,无法确定它应该采用哪个实例。但我找不到我的问题。

任何帮助都感激不尽。

4

1 回答 1

0

解决了...

我的'then.'有一个错误。这是我的“案例”而不是“何时”的一部分。这是解决方案:

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 似乎不是我的朋友。

UPDATE2: 更改“默认=无”并添加

.exclude(val_to_filter=None)

就在订购之前。似乎工作...

于 2017-03-27T15:08:59.700 回答