我有一个带有几条记录的Queryset,我不想使用相关的模型字段删除重复项。例如:
class User(models.Model):
group = models.ForeignKey('Group')
...
class Address(models.Model):
...
models.ForeignKey('User')
addresses = Address.objects.filter(user__group__id=1).order_by('-id')
这将返回一个地址记录的QuerySet,我想按用户ID分组。
.annotate
,因为我需要来自地址的所有字段,以及地址和用户之间的关系.distinct()
因为它不起作用,因为所有地址都是不同的,我想要不同的用户地址。我可以:
addresses = Address.objects.filter(user__group__id=1).order_by('-id')
unique_users_ids = []
unique_addresses = []
for address in addresses:
if address.user.id not in unique_users_ids:
unique_addresses.append(address)
unique_users_ids.append(address.user.id)
print unique_addresses # TA-DA!
但对于一个简单的事情来说似乎太过分了(该死的Django)。
有没有简单的方法来实现这一目标?
答案 0 :(得分:4)
.distinct()
使用字段名称 Django还有一个.distinct(..)
函数,它将列名称作为输入列,应该是唯一的。唉大多数数据库系统都不支持这个(据我所知只有PostgreSQL)。但是在PostgreSQL中我们可以执行:
# Limited number of database systems support this
addresses = (Address.objects
.filter(user__group__id=1)
.order_by('-id')
.distinct('user_id'))
处理此问题的另一种方法是首先使用一个适用于用户的查询,并为每个用户获取最大的address_id
:
from django.db.models import Max
address_ids = (User.objects
.annotate(address_id=Max('address_set__id'))
.filter(address_id__isnull=False)
.values_list('address_id'))
现在,对于每个用户,我们计算出最大的对应address_id
,并且我们消除了没有地址的User
。然后,我们获取id
s。
在第二步中,我们获取地址:
addresses = Address.objects.filter(pk__in=address_ids)