Django开发人员似乎意识到在MySQL中没有办法过滤这样的计算字段:
SomeModel.objects.extra(select={ 'total': 'SOME CALCULATION GOES HERE' }, where=['total < 10'])
OR
SomeModel.objects.extra(select={ 'total': 'SOME CALCULATION GOES HERE' }).filter(total__lt=10)
这在https://code.djangoproject.com/ticket/8784中有所描述,但不幸的是,看起来需要一年的时间来实现目前的速度。我理解开发团队的关注,理想情况下他们想要摆脱.extra(),因为通过在该语句中编写纯SQL代码变得非DB无关。我认为在许多项目中处理计算字段是相当常见的任务,我目前面临的问题是我无法解决:我认为大多数社区经常使用这种肮脏的解决方法:
SomeModel.objects.extra(select={ 'total': 'SOME CALCULATION GOES HERE' }, where=['1 HAVING total < 10'])
实际上它可以工作,但直到您需要在上述语句的结果上添加过滤器的那一刻:
SomeModel.objects.extra(select={ 'total': 'SOME CALCULATION GOES HERE' }, where=['1 HAVING total < 10']).filter(id__gt=300)
这不再起作用,因为它转换为错误的SQL语句:
SELECT id, ..., (SOME CALCULATION) AS total
FROM some_table
WHERE (1 AND HAVING total < 10 AND id > 300)
我想要实现的是在自定义模型管理器中有某种限制,这将允许我编写这样的代码:
class SomeModelManager(models.Manager):
def apply_total_restriction(self, restriction_num):
return self.extra(select={ 'total': 'CALCULATION GOES HERE' }).filter(total__lt=restriction_num)
...
SomeModel.objects.apply_total_restriction(restriction_num).filter(created_by_id__exact=1)
问题是:有人知道如何克服这种暂时的(希望)限制并完成任务吗?任何可能的替代方案?
答案 0 :(得分:0)
我找到了解决方案:我认为在WHERE子句中再次计算该字段会太慢,但是当我尝试它时它变得非常快并且不需要HAVING。以下是我的意思:
SELECT (a + b / 2) as 'c', a, b
FROM table
WHERE (a + b / 2) >= 20 AND a != b
基本上就是这样 - 如果你认为你需要HAVING,试着用HAVING测量时间并再次计算计算字段并在WHERE中过滤它然后得出结论来比较时间。