如何在Django REST框架中使用嵌套序列化器时排除父级?

1 投票
1 回答
2585 浏览
提问于 2025-04-18 14:02

我觉得这个问题可能在文档里有说明,但我就是搞不明白。

如果我有一个序列化器里面包含了一个外键(ForeignKey),那么当这个序列化器嵌套在相关对象里面的时候,我该怎么把这个外键排除掉呢?

class EmployerSerializer(serializers.HyperlinkedModelSerializer):
    class Meta:
        model = Employer
        fields = ('name', 'person')

class PersonSerializer(serializers.HyperlinkedModelSerializer):
    employers = EmployerSerializer()

    class Meta:
        model = Person
        fields = ('name', 'employers')
        depth = 1

当我访问这个API:http://0.0.0.0:8000/person/1/,它会列出一些内容,比如:

{
    "name": "Joe Blow",
    "employers": {
        "name": "Acme Inc."
        "person": "http://0.0.0.0:8000/person/1/"
        }
}

在“employers”这个部分,“person”这个键是自引用的,而且是多余的,但只有当序列化器嵌套在它所指向的对象里面时才会这样。

看起来应该有个选项可以在序列化器嵌套时把它排除掉,但我就是找不到这个方法。

1 个回答

7
class DynamicFieldsModelSerializer(serializers.HyperlinkedModelSerializer):
    """
    A HyperlinkedModelSerializer that takes an additional `fields` argument that
    controls which fields should be displayed.
    """

    def __init__(self, *args, **kwargs):
        # Don't pass the 'fields' arg up to the superclass
        fields = kwargs.pop('fields', None)
        exclude = kwargs.pop('exclude', None)
        # Instantiate the superclass normally
        super(DynamicFieldsModelSerializer, self).__init__(*args, **kwargs)

        if fields:
            # Drop any fields that are not specified in the `fields` argument.
            allowed = set(fields)
            existing = set(self.fields.keys())
            for field_name in existing - allowed:
                self.fields.pop(field_name)
        if exclude:
            # Drop fields that are specified in the `exclude` argument.
            excluded = set(exclude)
            for field_name in excluded:
                try:
                    self.fields.pop(field_name)
                except KeyError:
                    pass
class EmployerSerializer(DynamicFieldsModelSerializer):
    class Meta:
       model = Employer
       fields = ('name', 'person')


class PersonSerializer(serializers.HyperlinkedModelSerializer):
    employers = EmployerSerializer(exclude=('name',))
    class Meta:
        model = Person
        fields = ('name', 'employers')
        depth = 1

用动态字段模型序列化器来扩展雇主序列化器

撰写回答