我正在尝试通过相关模型的存在对对象进行过滤和排序,最后强制为空。
示例模型:
class ModelA(models.Model):
name = models.CharField(max_length=255)
...
class ModelB(models.Model):
model_a = models.ForeignKey(ModelA, related_name=model_b)
date = models.DateField()
time = models.TimeField()
...
现在,我需要按某些kwargs(正常操作)过滤ModelA,但是我还需要按最近的ModelB日期和时间(以后,而不是过去)升序或无论使用升序还是降序,都必须使用单个查询参数降序和 NULL放在最后。
我已经得出结论,我需要覆盖默认的QuerySet order_by:
class ModelAQuerySet(models.QuerySet):
def order_by(self, *field_names):
if 'model_a_date' in field_names or '-model_a_date' in field_names:
field_names = list(field_names)
if 'model_a_date' in field_names:
field_names.remove('model_a_date')
return super().order_by(
'model_b__date',
'model_b_time',
*field_names
)
else:
field_names.remove('-model_a_date')
return super().order_by(
'-model_b__date',
'-model_b__time',
*field_names
)
else:
return super().order_by(*field_names)
当我对降序('-model_a_date'
)进行排序时,效果很好,因为NULL是最后一个,但是我很难将空值以升序放置在最后。我已经尝试过:
return super().order_by(
F('model_b').asc(nulls_last=True),
'model_b__date',
'model_b__time',
*field_names
)
####
return super().order_by(
F('model_b').asc(nulls_last=True)
).order_by(
'model_b__date',
'model_b_time',
*field_names
)
####
return super().order_by(
'model_b__date',
'model_b_time',
*field_names
).order_by(
F('model_b').asc(nulls_last=True),
)
但这根本不起作用。在我将order_by连同其他参数一起放入时,或者在上面的order_by之前或之后作为单独的order_by。
有什么想法吗?有没有人碰到过这样的问题?我在这里泡菜,老实说我没主意了。预先感谢。
编辑
我也这样尝试过.union:
ModelA.objects.annotate(
modelbs=Count('modelb')
).filter(
modelbs__gt=0
).union(
ModelA.objects.annotate(
modelbs=Count('model_b')
).filter(
modelbs=0
)
)
但这会出现错误:
ORDER BY term does not match any column in the result set.
答案 0 :(得分:1)
如果您使用链条,则可以:
这有意义吗?