1

给定一个引用自定义序列化程序的序列化程序:

class IndustryIdeaSerializer(serializers.ModelSerializer):
    sub_industry = IndustrySerializer(many=False, read_only=True)
    class Meta:
        model = myModels.IdeaIndustry
        fields = (
            'id'
            , 'sub_industry'
    )

当我发布像 { sub_industry: 12 } 或 { sub_industry_id: 12 } 这样的 JSON 时,我无法保存对此类的更改

它确实返回了正确的 JSON 来显示数据,我不会从这个角度改变它。但是将其更改为:

class IndustryIdeaSerializer(serializers.ModelSerializer):
    class Meta:
        model = myModels.IdeaIndustry
        fields = (
            'id'
            , 'sub_industry'
    )

给我保存操作(可以使用简单的 JSON),但不是读取操作(不返回与该外键关联的所有数据)!

首先我错过了一些明显的东西吗?是否有一种模式来处理我所追求的行为 - 即读取并返回深层树,但只保留 Id

4

2 回答 2

1

这适用于 DRF 3.0。我今天下午刚把这个搞定,如果我遇到任何不可预见的问题,我会跟进(同样,如果你发现任何问题,请告诉我!我对 DRF 还很陌生)

class EnhancedPrimaryKeyRelatedField(serializers.PrimaryKeyRelatedField):
'''
    This custom field extends the PrimaryKeyRelatedField

    It overrides to_representation (which generates the data to be
    serialized) to use a given serializer.

    This allows other serializers to show nested data about a related
    field, while still allowing the client to set relations by simply
    passing an id.

    To initialize, pass the queryset and serializer arguments.
    The serializer argument should be a Serializer class.

    If the serializer provides Meta.model (such as a ModelSerializer),
    and you wish to use the queryset provided by that serializer, you may
    omit the queryset argument.

    e.g.
    # without queryset
    child_object = EnhancedPrimaryKeyRelatedField(
        serializer=ChildObjectSerializer
    )

    # with queryset
    child_object = EnhancedPrimaryKeyRelatedField(
        queryset=models.ChildObject.objects.all(),
        serializer=SomeSpecializedSerializer
    )
'''
def __init__(self, *args, **kwargs):
    assert 'serializer' in kwargs
    self.serializer = kwargs['serializer']
    del kwargs['serializer']

    if 'queryset' not in kwargs:
        # Catch any programmer errors
        assert 'Meta' in self.serializer.__dict__
        assert 'model' in self.serializer.Meta.__dict__
        kwargs['queryset'] = self.serializer.Meta.model.objects.all()

    super(serializers.PrimaryKeyRelatedField, self).__init__(*args, **kwargs)

def to_representation(self, data):
    if hasattr(data.pk, 'all'):  # are we dealing with a collection?
        return self.serializer(data.pk.all(), many=True).data
    elif hasattr(data, 'pk') and data.pk:
        return self.serializer(self.queryset.get(pk=data.pk)).data
    else:
        return data.pk
于 2014-12-10T20:21:42.930 回答
0

没有任何内置的东西可以明确地处理这个问题,但是最近它已经出现了几次(例如在这里,所以也许我们需要让它变得更容易。

解决方法是继承 PrimaryKeyRelatedField,它将处理设置关系并覆盖to_native以提供您所追求的完整序列化。

我希望这会有所帮助。

于 2013-10-29T13:31:39.817 回答