如何覆盖 get_queryset 方法以仅显示包含在 Django 中的多对多字段中的对象?

How to overwrite get_queryset method to only display the objects that are contained within a many-to-many field in django?

我有一个 API 有两个型号。 BuildingsBuildingGroup。每个建筑都在一个建筑群中。

我想覆盖 get_queryset 方法以仅显示建筑组内的建筑。

我的模特:

class Building(models.Model):
    name  = models.CharField(max_length=120, null=True, blank=True)

    def __str__(self):
        return self.name


class BuildingGroup(models.Model):
    description = models.CharField(max_length=500, null=True, 
    buildings = models.ManyToManyField('Building')

我目前的看法:

class BuildingGroupAPIView(
                      mixins.RetrieveModelMixin,
                      ListAPIView):

    permission_classes          = [permissions.IsAdminUser]
    authentication_classes      = [SessionAuthentication]

    serializer_class = BuildingSerializer
    passed_id = None

    def get_queryset(self):
        qs = BuildingGroup.buildings.all()
        query = self.request.GET.get('q')
        if query is not None:
            qs = qs.filter(project__icontains=query)
        return qs

    def get_object(self):
        request = self.request
        passed_id = request.GET.get('id', None) or self.passed_id
        queryset = self.get_queryset()
        obj = None
        if passed_id is not None:
            obj = get_object_or_404(queryset, id=passed_id)
            self.check_object_permissions(request, obj)
        return obj

我的序列化器:

class BuildingSerializer(serializers.ModelSerializer):

    class Meta:
        model = Building

        fields = (
                'name',
                'height'
                'width'
        )

这显示了所有建筑物的列表。现在我想改变那个方法,但到目前为止我做不到。

我试过了:

qs = BuildingGroup.objects.buildings.all()
qs = BuildingGroup.buildings.all()
qs = BuildingGroup.buildings_set.all()

我尝试循环遍历 BuildingGroup...

有人有想法吗?非常感谢您的帮助。提前致谢

希望你需要过滤掉m2m关系,

def get_queryset(self):
    <b>qs = Building.objects.all()</b>
    query = self.request.GET.get('q')
    if query is not None:
        qs = qs.<b>filter(name=query)</b>
    return qs

我们可以用反向关系来查询。请检查下面的代码。我没有测试它,但它应该可以工作。

def get_queryset(self):
    qs = Building.objects.all()
    query = self.request.GET.get('q')
    if query is not None:
        qs = qs.filter(buildinggroup_set__description__icontains=query)
    return qs

首先像这样对 BuildingGroup 模型中的 buildings 字段进行轻微更改,删除引号以便它调用 建筑模型

buildings = models.ManyToManyField(Building)

所以,假设您有两个 Building 模型,

building1 = Building.objects.get(id=1)
building2 = Building.objects.get(id=2)

和一个 BuildingGroup 模型,

building_group = BuildingGroup.objects.get(id=2)

然后将以下 buildings 添加到 BuildingGroup 中,

building_group.buildings.add(building1)
building_group.buildings.add(building2)

要获取添加到 BuildingGroup 实例的所有建筑物的列表,您可以使用

building_group.buildings.all()

让我知道进展如何。祝你好运。

编辑。您似乎在这里调用了整个模型:

qs = BuildingGroup.buildings.all()

它应该是 BuildingGroup 实例。

building_group = BuildingGroup.objects.get(id='id')
qs = building_group.buildings.all()