我有一个这样的模型:
class Portfolio(models.Model):
user = models.ForeignKey(settings.AUTH_USER_MODEL)
project = models.ForeignKey(ProjectDetail, null=True, blank=True)
image = models.ImageField(upload_to=get_upload_path, max_length=500, null=True, blank=True)
caption = models.CharField(_('Caption'), max_length=200, blank=True, null=True)
added_on = models.DateTimeField(auto_now_add=True)
我想找到三个按add_on日期和不同用户排序的投资组合。
I.e。:像这样的东西
Portfolio.objects.all().order_by('-added_on').distinct('user')[:3]
我知道这可以在postgresql
中使用但不在mysql
中,是否有任何方法可以使用mysql
获得相同的最终结果?
答案 0 :(得分:1)
实际上.distinct([*fields])
仅适用于PostgresSQL
请参阅distinct文档
您可以使用与此
Portfolio.objects.order_by('-added_on').values('user').distinct()
咨询values个文档。 希望有所帮助。
答案 1 :(得分:0)
这可以是一种不可知的数据库方法:
from django.db.models import Max
#select the last 3 user touching Portfolio:
last3users = (User
.objects
.annotate(last_touch=Max('portfolio__added_on'))
.order_by('-last_touch')
)[:3]
#select last portfolio for each user
last3portfolios = [ Portfolio.objects.filter( user = u ).last('added_on')
for u in last3users ]
正如您所看到的,您将获得4个数据库访问而不是一个是在这种情况下要支付的价格,以使这段代码不受特定数据库功能的影响,在这种情况下似乎是合理的。 免责声明:未经过测试
答案 2 :(得分:0)
from django.db.models import Max, F
(Portfolio.objects.order_by('added_on')
.annotate(most_recent=Max('user__portfolio__added_on'))
.filter(most_recent=F('added_on'))[:3])
可以过滤注释。 most_recent=Max('user__portfolio__added_on')
将使用该投资组合用户的最新added_on
日期为每一行添加注释。 F
对象允许您根据数据库字段的值进行过滤。
请注意,这不会处理added_on
对多个条目具有相同值的边缘情况。如果您经常使用bulk_create
创建多个对象,这可能会成为一个问题(虽然我甚至不知道它是否正确处理auto_add_now
选项)。