如何使用来自特定多对多实体的信息来注释字段?
How to annotate a field with information from a specific manytomany entity?
我有 2 个模型,然后 属性 和所有者之间存在多对多关系,它们大致如下:
class Property(models.Model):
name = models.CharField(max_length=50)
owners = models.ManyToManyField('Owner', through='PropertyOwner')
...
class Owner(models.Model):
name = models.CharField("Owner's name", max_length=50)
...
class PropertyOwner(models.Model):
property = models.ForeignKey('Property', on_delete=models.CASCADE)
owner = models.ForeignKey('Owner', on_delete=models.CASCADE)
current = models.BooleanField()
如何使用当前所有者的 ID 注释我的 Property.objects.all()
查询集中的新字段。 (也许使用 .first()
)
一个简单的方法是创建一个 属性,它将进行查询(根据 Property
)以获取当前所有者。因此看起来像:
class Property(models.Model):
name = models.CharField(max_length=50)
owners = models.ManyToManyField('Owner', through='PropertyOwner')
@property
def current_owner(self):
return self.owners.filter(<strong>propertyowner__current=True</strong>).first()
如果我们加载很多 Property
,并且我们需要为每个 Property
找到当前所有者,这将导致很多查询。
另一种方法可能是查询以当前所有者的主键获取 Property
s,然后加载所有这些所有者,最后将这些所有者分配给 Property
对象.因此看起来像:
我们可以用当前所有者的主键注解QuerySet
,然后批量获取这些并在Django中实现JOIN逻辑:
from operator import attrgetter
properties = list(Property.objects.filter(
propertyowner__current=True
).annotate(
current_owner_id=F('owners__pk')
))
owners = set(map(attrgetter('current_owner_id'), properties))
owners = {
owner.pk: owner
for owner in Owner.objects.filter(pk__in=owners)
}
for property in properties:
property.current_owner = owners.get(property.current_owner_id)
在此代码片段之后,properties
是具有额外属性的 Property
对象的列表:.current_owner
这是当前拥有者的 Owner
对象Property
.
我有 2 个模型,然后 属性 和所有者之间存在多对多关系,它们大致如下:
class Property(models.Model):
name = models.CharField(max_length=50)
owners = models.ManyToManyField('Owner', through='PropertyOwner')
...
class Owner(models.Model):
name = models.CharField("Owner's name", max_length=50)
...
class PropertyOwner(models.Model):
property = models.ForeignKey('Property', on_delete=models.CASCADE)
owner = models.ForeignKey('Owner', on_delete=models.CASCADE)
current = models.BooleanField()
如何使用当前所有者的 ID 注释我的 Property.objects.all()
查询集中的新字段。 (也许使用 .first()
)
一个简单的方法是创建一个 属性,它将进行查询(根据 Property
)以获取当前所有者。因此看起来像:
class Property(models.Model):
name = models.CharField(max_length=50)
owners = models.ManyToManyField('Owner', through='PropertyOwner')
@property
def current_owner(self):
return self.owners.filter(<strong>propertyowner__current=True</strong>).first()
如果我们加载很多 Property
,并且我们需要为每个 Property
找到当前所有者,这将导致很多查询。
另一种方法可能是查询以当前所有者的主键获取 Property
s,然后加载所有这些所有者,最后将这些所有者分配给 Property
对象.因此看起来像:
我们可以用当前所有者的主键注解QuerySet
,然后批量获取这些并在Django中实现JOIN逻辑:
from operator import attrgetter
properties = list(Property.objects.filter(
propertyowner__current=True
).annotate(
current_owner_id=F('owners__pk')
))
owners = set(map(attrgetter('current_owner_id'), properties))
owners = {
owner.pk: owner
for owner in Owner.objects.filter(pk__in=owners)
}
for property in properties:
property.current_owner = owners.get(property.current_owner_id)
在此代码片段之后,properties
是具有额外属性的 Property
对象的列表:.current_owner
这是当前拥有者的 Owner
对象Property
.