【问题标题】:id field in django rest framework serializerdjango rest 框架序列化程序中的 id 字段
【发布时间】:2013-02-07 11:58:52
【问题描述】:

我正在使用 django rest 框架,只是创建一个简单的序列化器,如下所示:

class PackageSerializer(serializers.HyperlinkedModelSerializer):

    class Meta:
        model = Package
        fields = ('id', 'url', 'title','location')

但是我得到了这个错误:

KeyError at /cerberus/packages/
'id'

为什么我无法将主键“id”作为序列化数据的一部分?感谢您的帮助!

【问题讨论】:

    标签: django django-rest-framework


    【解决方案1】:

    HyperlinkedModelSerializer 默认不包含id。在 2.2 及更早版本中,您需要将其显式添加为字段...

    class PackageSerializer(serializers.HyperlinkedModelSerializer):
        id = serializers.Field()
    
        class Meta:
            model = Package
            fields = ('id', 'url', 'title','location')
    

    从 2.3 开始,您可以简单地将 'id' 添加到 fields 选项...

    class PackageSerializer(serializers.HyperlinkedModelSerializer):
        class Meta:
            model = Package
            fields = ('id', 'url', 'title','location')
    

    从 3.x (fields 选项,则必须使用 ReadOnlyField() 而不是 Field()...

    class PackageSerializer(serializers.HyperlinkedModelSerializer):
        id = serializers.ReadOnlyField()
    
        class Meta:
            model = Package
    

    【讨论】:

    • 这个技巧帮助我完成了 rest_framework [链接] (django-rest-framework.org/tutorial/…) 的教程。在教程中有一行pk = serializers.Field(),但它应该是id = serializers.Field()。我监督了那个错字。
    • 对于 Django Rest Framework 3.x,现在应该是 id = serializers.ReadOnlyField()
    • 谢谢..很好的解释!!
    • 从版本 3.3.0 开始,不推荐使用没有“字段”属性或“排除”属性的 ModelSerializer。因此,第三个代码示例将失败并返回 AssertionError
    • 而在 From "3.x (所有 _' ??
    【解决方案2】:

    我只是通过创建这个类对其进行了调整以使其更具可插入性:

    class HyperlinkedModelSerializerWithId(serializers.HyperlinkedModelSerializer):
        """Extend the HyperlinkedModelSerializer to add IDs as well for the best of
        both worlds.
        """
        id = serializers.ReadOnlyField()
    

    然后,只需使用它来制作您的序列化程序,您就可以开始了。

    【讨论】:

    • 非常优雅。谢谢!!
    【解决方案3】:

    根据Django Rest Framework Documentation

    默认隐式生成的 id 字段被标记为只读。这会导致它在更新时被删除。

    因此,如果您需要在更新方法中使用id 字段,则不能将其声明为只读,而是使用可读写字段:

    class PackageSerializer(serializers.ModelSerializer):
        id = serializers.IntegerField()
    

    【讨论】:

    • 你不应该在序列化模型上声明 pk
    • @AlxVallejo 如果您希望能够创建具有特定 id 而不是自动 id 的实例,您可以这样做
    • 我想不出你会用其他东西覆盖模型的 ID 以进行序列化
    • 将 64 位 id 转换为有效的 Javascript 字符串,就像 Facebook 所做的那样。 (见developers.facebook.com/docs/workplace/reference/graph-api)。 Base64 URL 编码一个 id,就像 Instagram 一样。
    猜你喜欢
    • 2020-12-28
    • 1970-01-01
    • 2014-11-25
    • 1970-01-01
    • 2015-09-01
    • 1970-01-01
    • 2016-11-16
    • 1970-01-01
    • 2017-01-12
    相关资源
    最近更新 更多