问题描述
我有 2 个类,国家和坐标。在对 Country 表进行 API 调用时,我希望 API(使用 DRF)也返回相关的坐标信息。
默认情况下,可以理解地返回以下内容 (localhost:8000/api/country/):
{
"id": 1,"name": "TestCountry","coordinates": 1
}
问题是在我的 views.py 文件中实现 select_related 并修改 CountrySerializer 后,输出保持完全相同。我曾期待这样的事情:
{
"id": 1,"coordinates": {
"longitude": 123,"latitude": 456,}
}
或者即使这样就足够了:
{
"id": 1,"longitude": 123,}
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” 引用坐标表。这是错误还是与不正确的实施有关?
解决方法
请注意,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')
还使用像 coordinatesID
这样的字段名称在 Django 中并不是很好的命名约定,因为你会有一个像 coordinatesID.id
这样的属性,它不是很干净。
https://docs.djangoproject.com/en/3.2/topics/db/examples/many_to_one/