我有看起来像这样的 Django 模型
class Solution(models.Model):
score = models.IntegerField();
data = models.TextField();
class SolutionAuthors(models.Model):
sol = models.ForeignKey(Solution);
user = models.ForeignKey(User);
date_solved = models.DateField()
我想查询每个解决方案的最新 SolutionAuthor。
等效的 SQL 可能如下所示
SELECT * FROM Solutions s INNER JOIN SolutionAuthor sa ON sa.sol=s.sol
WHERE sa.id = ( SELECT TOP 1 sa_id FROM SolutionAuthor sa2 WHERE sa2.sol=s.sol
ORDER BY date_solved )
关于如何使用 annotate 功能或其他方式执行此操作的任何想法?重组模式的解决方案也很受欢迎。
请您参考如下方法:
您有 > 8K 代表,这意味着:
- 您知道无法在注释上编写过滤器。
- 您可以编写
解决方案model method 获取最新的解决方案。
这是一个模型方法的示例解决方案,不需要在查询中注释,因为您可以随时调用方法:
class Solution(models.Model):
score = models.IntegerField()
data = models.TextField()
@method
def last_solution(self):
return self.objects.solutionauthors_set.latest('date_solved')
如果这不是您的方法,可能是因为性能问题 或因为您无法通过模型方法在查询中包含过滤器。如果这是我的应用程序,我的解决方案将是将最后一个 solution author 保留到 solution 模型:
class Solution(models.Model):
score = models.IntegerField()
data = models.TextField()
#new persisted field:
last_solution = models.ForeignKey('SolutionAuthors', null=True, blanc=True);
#keeping last_solution up to date:
#imports to handle signals:
from django.db.models.signals import post_save
from django.dispatch import receiver
#persisting data
@receiver(post_save, sender=SolutionAuthors)
def set_last_solution(sender, instance, signal, created, **kwargs):
if created or instance.date_solved > instance.sol.last_solution.date_solved:
instance.sol.last_solution = instance
instance.sol.save()
此方法将通过上一个解决方案提高任何查询的性能。 缺点是数据库的非规范化,但我认为必须改变对这个主题的态度。
