Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/django/20.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
Django 如何在rest框架中使用select_related_Django_Django Rest Framework - Fatal编程技术网

Django 如何在rest框架中使用select_related

Django 如何在rest框架中使用select_related,django,django-rest-framework,Django,Django Rest Framework,我是django的新手,我正在创建一个基本网站,用户可以在这个网站上发布一些消息,并在帖子中添加一些标签。我有3个模型的人,职位和标签。我使用rest框架为帖子创建了API,它应该给我一个带有人名的帖子列表,以及与帖子相关的标签。对于少量的帖子来说,这很好,但对于大型帖子来说,响应时间太长了。使用django工具栏,我能够发现触发的查询太多,所以我在queryset中使用了prefetch_related和select_related。在这里,查询的数量减少了一半,但对于外键关系,仍对每个记录执

我是django的新手,我正在创建一个基本网站,用户可以在这个网站上发布一些消息,并在帖子中添加一些标签。我有3个模型的人,职位和标签。我使用rest框架为帖子创建了API,它应该给我一个带有人名的帖子列表,以及与帖子相关的标签。对于少量的帖子来说,这很好,但对于大型帖子来说,响应时间太长了。使用django工具栏,我能够发现触发的查询太多,所以我在queryset中使用了prefetch_related和select_related。在这里,查询的数量减少了一半,但对于外键关系,仍对每个记录执行查询。下面是我的代码示例

为了获得10条记录,它在不使用与标签模型相关的预取_的情况下触发34个查询

在标签上使用预取_后,它是15个查询。现在,对于个人帖子,它正在对具有自连接的人发起查询。如何减少查询的数量

models.py

class Tag(models.Model):
    name = models.CharField(max_length=200,unique=True)

    def __str__(self):
        return self.name

class Person(models.Model):
    name = models.CharField(max_length=200,unique=True)
    friends = models.ManyToManyField("self", blank=True)

    def __str__(self):
        return self.name

class Post(models.Model):
    person_id = models.ForeignKey(Person)
    text = models.TextField(blank=True,null=True)
    related_tags = models.ManyToManyField(Tag)

    def __str__(self):
        return self.text



serilizers.py

class PostSerializer(serializers.HyperlinkedModelSerializer):

    @staticmethod
    def setup_eager_loading(queryset):
        queryset = queryset.select_related("person_id").prefetch_related("related_tags")
        return queryset

    class Meta:
        model = Post
        fields = ('url', 'id', 'text','related_tags','person_id')
        # fields = '__all__'
        depth = 1
views.py
class PostViewSet(viewsets.ModelViewSet):
    queryset = PostSerializer.setup_eager_loading(Post.objects.all())
    serializer_class = PostSerializer
下面是查询列表,分别列出了发生的情况

SELECT `myapp_post`.`id`, `myapp_post`.`person_id_id`, `myapp_post`.`text`, `myapp_person`.`id`, `myapp_person`.`name` 
FROM `myapp_post` INNER JOIN `myapp_person` ON (`myapp_post`.`person_id_id` = `myapp_person`.`id`)
LIMIT 10
发生-1次

SELECT (`myapp_post_related_tags`.`post_id`) AS `_prefetch_related_val_post_id`, `myapp_tag`.`id`, `myapp_tag`.`name`
FROM `myapp_tag` INNER JOIN `myapp_post_related_tags` ON (`myapp_tag`.`id` = `myapp_post_related_tags`.`tag_id`)
WHERE `myapp_post_related_tags`.`post_id` IN (11, 12, 13, 14, 15, 16, 17, 18, 19, 20)
SELECT `myapp_person`.`id`, `myapp_person`.`name`
FROM `myapp_person` INNER JOIN `myapp_person_related_persons` ON (`myapp_person`.`id` = `myapp_person_related_persons`.`to_person_id`)
WHERE `myapp_person_related_persons`.`from_person_id` = 704692
发生-1次

SELECT (`myapp_post_related_tags`.`post_id`) AS `_prefetch_related_val_post_id`, `myapp_tag`.`id`, `myapp_tag`.`name`
FROM `myapp_tag` INNER JOIN `myapp_post_related_tags` ON (`myapp_tag`.`id` = `myapp_post_related_tags`.`tag_id`)
WHERE `myapp_post_related_tags`.`post_id` IN (11, 12, 13, 14, 15, 16, 17, 18, 19, 20)
SELECT `myapp_person`.`id`, `myapp_person`.`name`
FROM `myapp_person` INNER JOIN `myapp_person_related_persons` ON (`myapp_person`.`id` = `myapp_person_related_persons`.`to_person_id`)
WHERE `myapp_person_related_persons`.`from_person_id` = 704692

发生-10次10条记录

尝试
选择相关(“人员”)
而不是
人员id
@Alasdair它表示在选择相关:“人员”中给出的字段名无效。选择是:对不起,我误读了你的模型。通常,您将拥有
person=models.ForeignKey(person)
,然后数据库列将是
person\u id
。如果您将模型字段命名为
person\u id
,则数据库列为
person\u id\u id
,这有点奇怪。请将查询添加到您的问题中。@Alasdair是的,命名是我的错误。我已经在这里写了所有查询。请尝试
select\u related(“person”)
而不是
person\u id
@Alasdair,因为select\u related:“person”中给出的字段名无效。选择是:对不起,我误读了你的模型。通常,您将拥有
person=models.ForeignKey(person)
,然后数据库列将是
person\u id
。如果您将模型字段命名为
person\u id
,则数据库列为
person\u id\u id
,这有点奇怪。请将查询添加到您的问题中。@Alasdair是的,命名是我的错误。我把所有的疑问都写在这里了。