【发布时间】:2020-04-28 11:17:40
【问题描述】:
我正在尝试通过相关模型的存在来过滤和排序对象,最后强制为空。
示例模型:
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 日期和时间(将来,而不是过去)升序或使用单个查询参数降序,并且 NULLS 需要放在最后,无论升序还是降序。
我已经得出结论,我需要覆盖默认的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') 时它工作正常,因为 NULLS 在最后,但我很难将空值按升序排列在最后。我已经试过了:
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.
【问题讨论】:
标签: python django django-models