【问题标题】:Django select_related Not Working as ExpectedDjango select_related 没有按预期工作
【发布时间】:2021-09-23 04:52:06
【问题描述】:

我有 2 个班级,国家和坐标。在对 Country 表进行 API 调用时,我希望 API(使用 DRF)也能返回相关的坐标信息。

默认情况下,可以理解地返回以下内容(localhost:8000/api/country/):

{
    "id": 1,
    "name": "TestCountry",
    "coordinates": 1
}

问题是在我的views.py文件中实现了select_related,并且修改了CountrySerializer之后,输出仍然完全一样。我曾期待过这样的事情:

{
    "id": 1,
    "name": "TestCountry",
    "coordinates": {
        "longitude": 123,
        "latitude": 456,
    }
}

甚至这样就足够了:

{
    "id": 1,
    "name": "TestCountry",
    "longitude": 123,
    "latitude": 456,
}

这里是模型、视图和序列化程序文件中的相关代码。

class Coordinates(models.Model):
    longitude = models.DecimalField()
    latitude = models.DecimalField()

class Country(models.Model):
    name = models.CharField()
    coordinatesID = models.ForeignKey(Coordinates, on_delete=models.SET_NULL, verbose_name="Coordinates", db_column="CoordinatesID", blank=True, null=True, related_name="coordinates")

class CountryViewSet(viewsets.ReadOnlyModelViewSet):
    queryset = Country.objects.select_related('coordinatesID').all()
    serializer_class = CountrySerializer

class CountrySerializer(DynamicFieldModelSerializer):
    longitude = serializers.ReadOnlyField(source='coordinates.longitude')
    latitude = serializers.ReadOnlyField(source='coordinates.latitude')

    class Meta:
        model = Country
        fields = '__all__'

另外,在 Country 表中,我指定了 related_name="coordinates",但是 select_related 无法识别此选项,我仍然必须使用 "coordinatesID" 引用坐标表。这是一个错误还是与不正确的实现有关?

【问题讨论】:

    标签: django django-rest-framework django-views django-admin django-select-related


    【解决方案1】:

    请注意,related_name 用于访问从 Coordinates 模型端到 Country 端的反向关系,而不是相反。

    所以在select_related 中,您可以使用模型本身定义的所有字段和关系,因此对于Country 模型,如果您将坐标关系定义为coordinatesID,您将需要这样做

    queryset = Country.objects.select_related('coordinatesID').all()
    

    并在序列化程序中使用

    longitude = serializers.ReadOnlyField(source='coordinatesID.longitude')
    latitude = serializers.ReadOnlyField(source='coordinatesID.latitude')
    

    在 django 中也使用像 coordinatesID 这样的字段名称不是很好的命名约定,因为你会有像 coordinatesID.id 这样的属性,它不是很干净。

    https://docs.djangoproject.com/en/3.2/topics/db/examples/many_to_one/

    【讨论】:

      猜你喜欢
      • 2023-03-30
      • 2013-09-02
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2023-02-22
      • 2019-05-25
      • 2018-09-11
      • 2013-01-08
      相关资源
      最近更新 更多