【问题标题】:How to add 'id' to the fields in HyperlinkedModelSerializer in DRF如何在 DRF 中的 HyperlinkedModelSerializer 中的字段中添加“id”
【发布时间】:2018-08-21 10:43:33
【问题描述】:

使用 Django REST Framework 中的 HyperlinkedModelSerializer 时,id 字段默认不包含在 fields 中。这个question 的答案很好地解释了这一点。

但是我有一个问题想以特定方式解决。

我有一个带有自定义 ID 和几十个其他字段的模型:

class Foo(models.Model):
    id = models.IntegerField(primary_key=True)
    # 20-30 fields

serializers.py 我想包含模型中的所有字段:

class FooSerializer(serializers.HyperlinkedModelSerializer):
    class Meta:
        model = Foo
        fields = '__all__'

但这不包括字段id。定义 id = serializers.ReadOnlyField() 也对我没有帮助,因为 id 应该是可编辑的。

像这样手动指定所有字段:

fields = ('id', # all other fields)

这将是我试图规避的解决方案,因为模型类有很多字段,并且它们将来可能会发生变化。

添加字段id 是否有很好的可能性?也许覆盖__init__ 方法?

【问题讨论】:

  • 你为什么不用class FooSerializer(serializers.ModelSerializer)
  • @argo 因为我需要明确的HyperlinkedModelSerializer

标签: python django django-rest-framework


【解决方案1】:

FooSerializer 序列化程序中添加 id 属性为:

class FooSerializer(serializers.HyperlinkedModelSerializer):
    id = serializers.IntegerField(read_only=True)
    class Meta:
        model = Foo
        fields = '__all__'

【讨论】:

  • 非常感谢!这确实优雅、简单且非常直接。
  • 简单胜于复杂!!
  • 除非你想让人们编辑id(这可能会导致问题),我建议将代码调整为:id = serializers.IntegerField(read_only=True)
【解决方案2】:

您可以创建自定义 HyperlinkedModelSerializer 并覆盖 get_default_field_names 以像普通 ModelSerializer 一样包含 id。

例子:

class CustomHyperlinkedModelSerializer(HyperlinkedModelSerializer ):

    def get_default_field_names(self, declared_fields, model_info):

        return (
            [model_info.pk.name] +
            [self.url_field_name] +
            list(declared_fields) +
            list(model_info.fields) +
            list(model_info.forward_relations)
         )

注意:这只是一个想法。我还没有测试过。

【讨论】:

  • 感谢您的努力。我设法通过覆盖__init__ 方法并操作字段来完成任务。但无论是那个还是你的提议看起来都不是很优雅而且令人困惑。
  • 这正是我们在最近的一个 API 项目中所做的。我们所做的唯一更改是将 url 字段移动到列表的底部。非常感谢!
【解决方案3】:

HyperlinkedModelSerializer 默认不包含id 字段。您可以将id 作为属性添加到序列化程序中,如下所示:

class FooSerializer(serializers.HyperlinkedModelSerializer):
    id = serializers.IntegerField()
    class Meta:
        model = Foo
        fields = '__all__'

【讨论】:

  • 感谢您的回答,但它不会为 Jerin Peter George 的第一个回答增加任何价值。
猜你喜欢
  • 2016-01-30
  • 2015-08-16
  • 1970-01-01
  • 1970-01-01
  • 2022-11-23
  • 1970-01-01
  • 2016-03-14
  • 1970-01-01
  • 2019-11-07
相关资源
最近更新 更多