【问题标题】:LIstSerializer AssertionErrorLIstSerializer AssertionError
【发布时间】:2019-06-17 07:04:54
【问题描述】:

我正在尝试使用 ListSerializer,以便可以在 POST 的列表中创建/反序列化多个对象。我按照https://www.django-rest-framework.org/api-guide/serializers/#listserializer 的指南进行操作,但在访问端点时似乎遇到了这个错误。

assert self.child is not None, '``child`` is a required argument.'

python3.7/site-packages/rest_framework/serializers.py in __init__, line 592

我的序列化器如下:

class PredictionListSerializer(serializers.ListSerializer):

    def update(self, instance, validated_data):
        pass

    def create(self, validated_data):
        predictions = [Prediction(**item) for item in validated_data]
        return Prediction.objects.bulk_create(predictions)
class NestedPredictionSerializer(serializers.ModelSerializer):
    id = serializers.IntegerField(read_only=True)
    # Nested Serializer
    data = DataSerializer()

    class Meta:
        model = Prediction
        list_serializer_class = PredictionListSerializer
        fields = ('id', 'specimen_id', 'data' 'date_added',)
        extra_kwargs = {
            'slug': {'validators': []},
        }
        datatables_always_serialize = ('id',)

在 ListSerializer 的初始化中抛出了断言错误,但是,序列化器正在像这样在 ViewSet 中初始化。

class BulkPredictionViewSet(viewsets.ModelViewSet):
    queryset = Prediction.objects.all()
    serializer_class = PredictionListSerializer

有人熟悉这个问题吗?我想知道我缺乏对序列化程序初始化的控制(因为我使用的是 ViewSet)是否会影响这一点。如果我尝试将 NestedPredictionSerializer 传递到 ViewSet 我得到"Invalid data. Expected a dictionary, but got list."

编辑:

我能够覆盖我的 ViewSet 中的 get_serializer 方法以设置 many=True 并将序列化程序作为我的 NestedPredictionSerializer 传递,它可以识别 POST 上的列表。 Howeber,现在我收到错误When a serializer is passed a ``data`` keyword argument you must call ``.is_valid()`` before attempting to access the serialized ``.data`` representation. You should either call ``.is_valid()`` first, or access ``.initial_data`` instead.

【问题讨论】:

    标签: python django django-rest-framework


    【解决方案1】:

    当遵循此阅读的建议并结合此答案时,我能够使 POST 和 GET 工作:https://stackoverflow.com/a/45651309/3439441

    我被覆盖的ViewSet.get_serializer 现在看起来像这样:

        def get_serializer(self, *args, **kwargs):
            if self.request.method.lower() == 'post':
                data = kwargs.get('data')
                kwargs['many'] = isinstance(data, list)
            return super(BulkPredictionViewSet, self).get_serializer(*args, **kwargs)
    

    【讨论】:

      【解决方案2】:

      只需将many=True 用于create action

      class BulkPredictionViewSet(viewsets.ModelViewSet):
          queryset = Prediction.objects.all()
          serializer_class = NestedPredictionSerializer
      
          def get_serializer(self, *args, **kwargs):
              serializer_class = self.get_serializer_class()
              kwargs['context'] = self.get_serializer_context()
              if self.action == 'create': 
                  kwargs['many'] = True
              return serializer_class(*args, **kwargs)
      

      您不需要使用PredictionListSerializer,因为many=True 会自动创建ListSerializer

      【讨论】:

      • 当我这样做时,POST 按预期工作,但是当我尝试在同一端点上执行 GET 时,我得到 AttributeError: 'PredictionListSerializer' object has no attribute 'fields' 所以,我尝试在其他情况下设置 many = False 但是引发另一个关于特定字段的错误。
      • 当我添加一个 else many=False 时:Got AttributeError when attempting to get a value for field `specimen_id` on serializer `NestedPredictionSerializer`. The serializer field might be named incorrectly and not match any attribute or key on the `list` instance. Original exception text was: 'list' object has no attribute 'specimen_id'.
      • @RubyJ 您需要从 NestedPredictionSerializer 类中删除 list_serializer_class = PredictionListSerializer 行。如果这无助于为您的问题添加完整的追溯。
      • 我不明白你的意思。我删除了那条线,我仍然得到同样的错误。如果我删除了覆盖的 get_serializer 方法,那么我不会在 GET 上得到异常,但是 POST 不会像原来的问题那样工作。
      • 我什至已经删除了整个PredictionListSerializer 代码。当我按照您的描述覆盖 get_serializer 时,GET 请求会遇到相同的错误 AttributeError: 'ListSerializer' object has no attribute 'fields'
      猜你喜欢
      • 1970-01-01
      • 2021-09-07
      • 1970-01-01
      • 2016-10-01
      • 2020-04-12
      • 2018-10-07
      • 1970-01-01
      • 1970-01-01
      • 2017-07-11
      相关资源
      最近更新 更多