【问题标题】:Django rest framework ListApiView slow queryDjango rest框架ListApiView慢查询
【发布时间】:2022-01-25 04:41:09
【问题描述】:

我有一个 147 行的显示表。我没有对这个数据集进行任何繁重的计算,我只需要从数据库中快速获取它。目前,加载时间为 3-4 秒。其他数据来得真快,为什么? ListApiView 工作慢吗?

@permission_classes([AllowAny])
class DisplaysList(generics.ListAPIView):
    queryset = Displays.objects.all()
    serializer_class = serializers.DisplaySerializer



class Displays(models.Model):
    name = models.CharField(max_length=45, blank=True, null=True)
    owner = models.CharField(max_length=45, blank=True, null=True)

class GeoLocation(models.Model):
    id = models.CharField(primary_key=True, max_length=32,
                          default=generate_uuid)
    display = models.ForeignKey(
        Displays, on_delete=models.CASCADE, blank=True, null=True)
    lat = models.DecimalField(max_digits = 30, decimal_places=20, blank=True, null=True)
    lon = models.DecimalField(max_digits = 30, decimal_places=20, blank=True, null=True)

我认为问题就在这里,如何有效地进行地理定位?

class DisplaySerializer(serializers.ModelSerializer):
    
    geolocation = serializers.SerializerMethodField()
    
    def get_geolocation(self, obj):
        gl = GeoLocation.objects.filter(display = obj)
        gll = list(gl.values)
        return gll

    class Meta:
        model = Displays
        fields = "__all__"
        

【问题讨论】:

  • 请出示您的型号和序列化程序
  • 试试这个:list(GeoLocation.objects.select_related().filter(display=obj).values())
  • @Ahtisham 仍然很慢,6 秒

标签: python django django-rest-framework django-views


【解决方案1】:

使用嵌套序列化程序,这样您就不必通过方法返回嵌套数据

class GeoLocationSerializer(serializers.ModelSerializer):

    class Meta:
        model = GeoLocation
        fields = "__all__"


class DisplaySerializer(serializers.ModelSerializer):
    
    geolocation_set = GeoLocationSerializer(many=True)

    class Meta:
        model = Displays
        fields = ["name", "owner", "geolocation_set"]

然后在您看来,使用prefetch_related 在单个查询中获取嵌套数据。这会将您的查询减少到只有两个

@permission_classes([AllowAny])
class DisplaysList(generics.ListAPIView):
    queryset = Displays.objects.all().prefetch_related("geolocation_set")
    serializer_class = serializers.DisplaySerializer

【讨论】:

  • @Iain Shelvington 他不能在这里使用select_related 吗?
  • @Ahtisham 我不确定你会在哪里使用select_related。我们正在使用prefetch_related 从反向关系中获取对象,但是没有外键关系可以使用select_related 吗?
  • 你是说当我们以相反的顺序获取关系时,它会变成多对一的情况?案例显示是外键定义的。
猜你喜欢
  • 2015-10-10
  • 2012-10-25
  • 2021-08-22
  • 1970-01-01
  • 1970-01-01
  • 2015-05-08
  • 2018-05-22
  • 2014-09-19
  • 1970-01-01
相关资源
最近更新 更多