Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/django/21.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python Django在一次调用中序列化多个对象_Python_Django_Django Rest Framework - Fatal编程技术网

Python Django在一次调用中序列化多个对象

Python Django在一次调用中序列化多个对象,python,django,django-rest-framework,Python,Django,Django Rest Framework,我想知道序列化时如何减少对数据库的调用次数: 我有以下两种型号: class House(models.Model): name = models.CharField(max_length = 100, null = True, blank = True) address = models.CharField(max_length = 500, null = True, blank = True) class Room(models.Model): hous

我想知道序列化时如何减少对数据库的调用次数:

我有以下两种型号:

 class House(models.Model):
     name = models.CharField(max_length = 100, null = True, blank = True)
     address = models.CharField(max_length = 500, null = True, blank = True)

 class Room(models.Model):
      house = models.ForeignKey(House)
      name  = models.CharField(max_length = 100)
有一个房子,它可以有多个房间

我正在使用django rest框架,并试图在内部级别将所有3个东西序列化在一起

 class HouseSerializer(serializers.ModelSerializer)
    rooms = serializers.SerializerMethodField('room_serializer')

    def room_serializer(self):
         rooms = Room.objects.filter(house_id = self.id) # we are in House serializer, so self is a house
         return RoomSerializer(rooms).data

    class Meta:
        model = House
        fields = ('id', 'name', 'address')
所以现在,对于我想要序列化的每一个房子,我需要为它的房间单独调用。这是可行的,但那是额外的电话。 (想象一下我试图把很多东西打包在一起!)

现在,如果我有100所房子,要序列化所有东西,我需要进行100次数据库点击,O(n)次

我知道如果我能收集到所有的信息,我可以把点击次数减少到2次。O(1)时间

我的问题是我该怎么做?让连载者开心

在完成两个调用之后,我是否可以以某种方式进行循环,将房间“附加”到房子,然后对其进行序列化?(允许我添加这样的属性吗?)


请注意,我不需要django rest序列化程序来允许我以这种方式更改文件室中的属性。这仅适用于GET。

在当前编写时,使用
序列化方法字段进行N+1查询。关于堆栈溢出,我已经讨论过几次了,一般来说,它与您所做的类似。您正在处理一对多关系,这种关系可以通过与
prefetch\u related
相同的方式进行优化

class HouseSerializer(serializers.ModelSerializer)
    rooms = RoomSerializer(read_only=True, source="room_set", many=True)

    class Meta:
        model = House
        fields = ('id', 'name', 'address', )
我所做的更改使用嵌套序列化程序,而不是在
SerializerMethodField
中手动生成序列化程序。我已经将其限制为
只读
,正如您提到的,您只需要在
GET
请求中使用它,并且可写序列化程序在Django REST Framework 2.4中存在问题

由于尚未设置
房间
->
房屋
关系的反向关系,因此它是默认的
房间集
。您可以(并且应该)通过在
外键
字段上设置
相关的\u名称
来覆盖此设置,并且您需要相应地调整


为了防止N+1查询问题,您需要覆盖视图上的查询集。对于一般视图,这将在
queryset
属性上完成,或者在
get\u queryset
方法中完成,如
queryset=House.objects.prefetch\u related('room\u set')
。这将请求所有相关房间以及
House
对象的请求,因此您将只有两个请求,而不是N+1个请求。

我希望我有多个投票权。感谢您为我节省了大约500个查询!这很有帮助。非常感谢。
class HouseSerializer(serializers.ModelSerializer)
    rooms = RoomSerializer(read_only=True, source="room_set", many=True)

    class Meta:
        model = House
        fields = ('id', 'name', 'address', )