我知道了
# models
class Building(models.Model):
...
class Flat(models.Model):
building = models.ForeignKey(Building)
class Profile(models.Model):
flats = models.ManyToManyField(Flat)
# logic
building = Building.objects.create()
flat_1 = Flat.objects.create(building=building)
flat_2 = Flat.objects.create(building=building)
profile = Profile.objects.create()
profile.flats.add(flat_1)
profile.flats.add(flat_2)
profiles = Profile.objects.filter(flats__building=building)
我有profiles
两个相同的个人资料。我如何用不同的flat
来对每个注释进行注释,例如:profiles.first().flat == flat_1
和profiles.last().flat == flat_2
?
也许Subquery()
,但如何?
UPD 在某些DRF列表视图中需要此功能。 JSON中的输出必须类似于:
[
{
"profile_id": 1,
"flat_id": 2
},
{
"profile_id": 1,
"flat_id": 3
}
]
答案 0 :(得分:2)
要获取该输出,您可以执行以下操作:
data = Profile.objects.all().values('flats', 'id')
return Response(data=data)
在您的DRF视图中。
答案 1 :(得分:0)
最后,我为满足您的确切需求编写了代码,但首先写了几篇有趣的文章。
在您的代码示例中,您仅创建了一个配置文件,我确定您不会得到 2个相等的Profile实例,而只有一个。
问题是,如果您有一个只有一个条目的QuerySet,则:
profiles.first() == profiles.last() # True
因为profile.first()
和profiles.last()
是同一实例。
您应该尝试创建2个配置文件实例:
building = Building.objects.create()
flat_1 = Flat.objects.create(building=building)
flat_2 = Flat.objects.create(building=building)
profile_1 = Profile.objects.create() # You coud/should use bulk_create here.
profile_2 = Profile.objects.create()
profile_1.flats.add(flat_1)
profile_2.flats.add(flat_2)
然后
profiles = Profile.objects.filter(flats__building=building)
将返回两个不同的配置文件对象。
在此示例之后,您发布并按配置文件过滤单位并获取值(如果您拥有一个以上的配置文件,这也适用)。
Flat.objects.filter(profile=profile_1).values('profile__id', 'id')
这将返回类似(“ id”代表单位id
s)的信息:
[
{
"profile__id": 1,
"id": 1
},
{
"profile__id": 1,
"id": 3
}
]
如果您不按个人资料过滤(并且有多个),则可能会得到类似的内容:
[
{
"profile__id": 1,
"id": 1
},
{
"profile__id": 2,
"id": 3
},
{
"profile__id": 2,
"id": 4
},
...
]
如前所示的过滤器添加注释,并获得所需的值:
Flat.objects.filter(profile=profile_1).annotate(
flat_id=F('id')
).annotate(
profile_id=F('profile__id')
).values(
'profile_id', 'flat_id'
)
将准确给出您想要的:
[
{
"profile_id": 1,
"flat_id": 2
},
{
"profile_id": 1,
"flat_id": 3
}
]
答案 2 :(得分:0)
您可以使用正确的序列化器和正确的批注进行操作:
序列化器:
class FlatSerializer(serializers.ModelSerializer):
class Meta:
model = Flat
fields = ('flat_id', 'building_id')
flat_id = serializers.CharField(read_only=True)
然后,我只查询Flats
而不是配置文件并进行序列化:
flats = Flat.objects \
.annotate(flat_id=F('id')) \
.filter(building=building)
serialized = FlatSerializer(flats, many=True)
print(serialized.data) # [ { flat_id: 1, building_id: 1 }, { flat_id: 2, building_id: 1 } ]
让我知道这是否对您有用