我有三个模型,名为"Route","Place","Place".

class Route(models.Model):
    place = models.ForeignKey(Place, on_delete=models.CASCADE, null=False, blank=False)
    day = models.IntegerField(null=False, blank=False)
    order = models.IntegerField(null=False, blank=False)

class Place(models.Model):
    name = models.CharField(null=False, blank=False)


class PlaceImage(models.Model):
    place = models.ForeignKey(Place, on_delete=models.CASCADE, null=False, blank=False)
    image = models.ImageField(null=False, blank=False)

我想显示路由和地点的图像的基础上路由模型. 原始代码是…

# views.py
response_obj = (Route.objects.filter(day=day).prefetch_related("place__image").order_by('order'))
serializer = RouteSerializer(response_obj, many=True, context={'request': request})

# Part of RouteSerializer in serializers.py
placeImage = serializers.SerializerMethodField("get_placeImage_prefetch_related")
def get_placeImage_prefetch_related(self, group):
   request = self.context.get('request')
   image = group.place.image
   return request.build_absolute_uri(image.first().image.url)

我有N +1个查询来获取像这样的位置图像

(0.000) SELECT "PLACE_IMAGE"."id", "PLACE_IMAGE"."place_id", "PLACE_IMAGE"."image", "PLACE_IMAGE"."created_at" FROM "PLACE_IMAGE" WHERE "PLACE_IMAGE"."place_id" = 80 ORDER BY "PLACE_IMAGE"."id" ASC LIMIT 1; args=(80,); alias=default
(0.000) SELECT "PLACE_IMAGE"."id", "PLACE_IMAGE"."place_id", "PLACE_IMAGE"."image", "PLACE_IMAGE"."created_at" FROM "PLACE_IMAGE" WHERE "PLACE_IMAGE"."place_id" = 79 ORDER BY "PLACE_IMAGE"."id" ASC LIMIT 1; args=(79,); alias=default
(0.000) SELECT "PLACE_IMAGE"."id", "PLACE_IMAGE"."place_id", "PLACE_IMAGE"."image", "PLACE_IMAGE"."created_at" FROM "PLACE_IMAGE" WHERE "PLACE_IMAGE"."place_id" = 78 ORDER BY "PLACE_IMAGE"."id" ASC LIMIT 1; args=(78,); alias=default

我如何才能解决这个n+1问题?

在www.example.com上,我试过

prefetch_related(Prefetch('place__image', queryset=PlaceImage.objects.all().only('image')))

但出现了错误.

AttributeError: 'PlaceImage' object has no attribute '_add_hints'

推荐答案

问题是.first(),你可以用[0]代替:

def get_placeImage_prefetch_related(self, group):
    request = self.context.get('request')
    image = group.place.image
    return request.build_absolute_uri(image[0].image.url)

可能根本就没有这样的形象.在这种情况下,您可以使用:

def get_placeImage_prefetch_related(self, group):
    request = self.context.get('request')
    try:
        image = group.place.image[0]
        return request.build_absolute_uri(image.image.url)
    except KeyError:
        pass  # return None

Django相关问答推荐

Django中有修改字段值的挂钩吗?

我找不到为什么我的DRF登录测试没有按预期工作

在AWS s3中获取项目的URL

如何在Django查询集中查询多对多字段内是否存在实例

如何在uwsgi中创建单个日志(log)文件?

如何在 Django 中设置与 Session 相关的字段

一次请求中更新整个Django模型

如何在两个字段上查找 django 模型的副本?

基于令牌的身份验证如何工作?

Django 模型:如何查找自动生成的字段列表

如何在 Django 模板中的计数器上进行 for 循环中断?

data._mutable= 在 Django REST 框架中为真

在 Django Admin change_list 视图中更改 list_editable 字段时保存 Django 模型

JSP模板继承

Django Calendar日历小部件?

Django:创建索引:非唯一,多列

如何使用基于类的视图处理表单(通过 get 或 post)?

Django Admin:如何在内联中显示模型上定义的属性?

如何将本地文件分配给 Django 中的 FileField?

Django 将多个模型传递给一个模板