【问题标题】:How to get string representation of PrimaryKeyRelatedField in JSON如何在 JSON 中获取 PrimaryKeyRelatedField 的字符串表示形式
【发布时间】:2026-01-12 10:00:02
【问题描述】:

我正在使用 Django REST 框架,而且我对这个东西还很陌生。

我想在我的 JSON 输出中使用字符串表示 manytomanyfield 和外键字段,而不是值。

models.py

class Movie(models.Model):
    """Movie objects"""
    name = models.CharField(max_length=128)
    directorName = models.ForeignKey(Director)
    genre = models.ManyToManyField(Genre)

serializers.py

class MovieSerializer(serializers.ModelSerializer):
    """
    Serialiazing all the Movies.
    """
    genre = serializers.PrimaryKeyRelatedField(many=True, queryset=Genre.objects.all())
    directorName = serializers.PrimaryKeyRelatedField(queryset=Director.objects.all())
    owner = serializers.ReadOnlyField(source='owner.username')
    class Meta:
        model = Movie
        fields = ('popularity',"directorName",'genre','imdbScore','name','owner')

JSON 输出

{"popularity":"90.0","directorName":1,"genre":[1,2,3],"imdbScore":"8.9","name":"Titanic"}

我得到的只是值,而不是 directorName 和流派的 display_name。

请建议我如何纠正这个问题。

编辑 [已解决] 您需要重写 PrimaryKeyRelatedField 的 to_representation() 方法,因为它返回 pk。

【问题讨论】:

    标签: python json django python-2.7 django-rest-framework


    【解决方案1】:

    为此,您需要覆盖PrimaryKeyRelatedFieldto_representation() 方法,因为它返回pk

    您可以创建一个继承自PrimaryKeyRelatedFieldMyPrimaryKeyRelatedField,然后覆盖其to_representation() 方法。

    现在返回字符串表示,而不是 PrimaryKeyRelatedField 返回的 value.pk。我使用 six.text_type() 而不是 str() 来处理 Python 2(unicode) 和 Python 3(str) 版本。

    from django.utils import six
    from rest_framework import serializers
    
    class MyPrimaryKeyRelatedField(serializers.PrimaryKeyRelatedField):
    
        def to_representation(self, value):
            return six.text_type(value) # returns the string(Python3)/ unicode(Python2) representation now instead of pk 
    

    您的serializers.py 将如下所示:

    class MovieSerializer(serializers.ModelSerializer):
        """
        Serialiazing all the Movies.
        """
        genre = MyPrimaryKeyRelatedField(many=True, queryset=Genre.objects.all())
        directorName = MyPrimaryKeyRelatedField(queryset=Director.objects.all())
        owner = serializers.ReadOnlyField(source='owner.username')
        class Meta:
            model = Movie
            fields = ('popularity',"directorName",'genre','imdbScore','name','owner')
    

    【讨论】:

    • 给我这个错误'Director' object is not iterable
    • 你能发布回溯吗?
    • 它已解决,实际上我将many=True 设置为directorName 这就是为什么它给了我'Director' object is not iterable 错误。但现在我得到这个东西而不是directorName - "directorName": "<rest_framework.relations.PKOnlyObject object at 0x7f40ac40ca50>",的字符串表示
    • 您需要在您的Director 模型上添加一个__str__ 方法。那么它应该可以工作了。
    • 我得到的 rest_framework.relations.PKOnlyObject 对象与 to_representation(self, value) 的值相同。我的解决方案是在我的自定义PrimaryKeyRelatedField 中覆盖use_pk_only_optimization 以返回False,因为this method
    【解决方案2】:

    最简单的大概是用StringRelatedField

    class MovieSerializer(serializers.ModelSerializer):
        directorName = serializers.StringRelatedField(many=True)
    
    class Director(Model):
        # [...]
        def __unicode__(self):
            return self.directorName
    

    但是,当您需要 Director 模型的不同表示时,这不起作用。在这种情况下,您需要使用自定义序列化程序(请参阅 Rahul Gupta 的回答)。

    【讨论】:

    • 但它给了我这个错误'Relational fields should not provide a queryset argument, '
    • 这是我的副本和过去的错误,StringRelatedField 不需要/接受查询集。
    最近更新 更多