在视图中显示外键关系时出现问题



我有一个Land模型,它有三个关系,其中一个是Letter,模型是:

class Letter(models.Model):
land = models.ForeignKey('Land', on_delete=models.DO_NOTHING)
image = models.ImageField(null=True, upload_to=letter_image_file_path)
text = models.TextField(null=True, blank=True)
def __str__(self):
return str(self.id)

它的串行器是

class LettersSerializer(serializers.ModelSerializer):
class Meta:
model = Letter
fields = ('id', 'text', 'image', 'land',)
read_only_fields = ('id',)

CCD_ 3串行器为:

class LandSerializer(serializers.ModelSerializer):
utm_points = UTMPointsSerializer(many=True, read_only=True)
letters = LettersSerializer(many=True, read_only=True)

他们的观点是:

class BasicViewSet(viewsets.ModelViewSet):
authentication_classes = (TokenAuthentication,)
permission_classes = (IsAuthenticated,)

class LandViewSet(BasicViewSet):
serializer_class = LandSerializer
queryset = Land.objects.all()
class UTMPointViewSet(BasicViewSet):
serializer_class = UTMPointsSerializer
queryset = UTMPoint.objects.all()

class LettersViewSet(BasicViewSet):
serializer_class = LettersSerializer
queryset = Letter.objects.all()

但当我发送GET请求时,它没有显示letters字段:这是响应:

{
"id": 1,
"utm_points": []
}

虽然CCD_ 6和CCD_。CCD_ 8模型具有CCD_。经过一些尝试和错误,我不知道为什么结果没有letters字段。

您需要向LetterSerializer解释使用什么序列化程序来序列化Land。您不能使用LandSerializer,因为这会创建一个循环依赖项,但更重要的是:可能是响应中的无限递归,因为Letterlandland then serializes its related字母等。

因此,我们为Land:制作了一个简单的串行器

classSimpleLandSerializer(serializers.ModelSerializer):
utm_points = UTMPointsSerializer(many=True, read_only=True)
class Meta:
model = Land
fields = ['utm_points']

然后在CCD_ 18:的串行器中使用

class LettersSerializer(serializers.ModelSerializer):
land = SimpleLandSerializer()
class Meta:
model = Letter
fields = ('id', 'text', 'image', 'land',)
read_only_fields = ('id',)

EDIT:您也可以使用主键进行序列化,在这种情况下,您可以使用PrimaryKeyRelatedField[drf-doc]:进行序列化

class LettersSerializer(serializers.ModelSerializer):
land = PrimaryKeyRelatedField()
class Meta:
model = Letter
fields = ('id', 'text', 'image', 'land',)
read_only_fields = ('id',)

EDIT 2:另一个问题是您的letters关系不存在,如果您想将关系从letter_set重命名为letters,请使用:

class Letter(models.Model):
land = models.ForeignKey(
'Land',
related_name='letters',
on_delete=models.DO_NOTHING
)

最新更新