【问题标题】:Django Rest Framework create multiple objectsDjango Rest Framework 创建多个对象
【发布时间】:2019-01-06 07:11:59
【问题描述】:

这是我目前所拥有的。

我的序列化器:

class MySerializer(serializers.ModelSerializer):

     class Meta:
         model = MyModel
         fields = ('field_1', 'field_2', 'field_3')

我的模型视图集

class MyViewSet(ModelViewSet):

    serializer_class = MySerializer
    model = MyModel
    queryset = MyModel.objects.all().order_by('date_paid')

    def create(self, request, *args, **kwargs):
        many = True if isinstance(request.data, list) else False
        serializer = MySerializer(data=request.data, many=many)
        if serializer.is_valid():
            serializer.save()
        else:
            return Response(serializer.errors, 
status=status.HTTP_400_BAD_REQUEST)
        return Response(serializer.data, status=status.HTTP_201_CREATED)

我主要担心的是,在测试端点以使用以下有效负载创建多个对象时,在视图中 request.data 属性似乎为空,因此它返回缺少字段的错误。

{
        'data': [
            {
                'type': 'MySerializer',
                'attributes': {
                    'field_1': 1,
                    'field_2': 0.05,
                    'field_3': 'abc'
                }
            },
            {
                'type': 'MySerializer',
                'attributes': {
                    'field_1': 1,
                    'field_2': 0.05,
                    'field_3': 'abc'
                }
            },
            {
                'type': 'MySerializer',
                'attributes': {
                    'field_1': 1,
                    'field_2': 0.05,
                    'field_3': 'abc'
                }
            }
        ]
    }

但是当使用单个对象实例时:

{
        'data': {
            'type': 'MySerializer',
            'attributes': {
                    'field_1': 1,
                    'field_2': 0.05,
                    'field_3': 'abc'
            }
        }
    }

它似乎工作得很好并且对象被创建了。

我尝试了几种方法来容纳有效负载:

  • 将对象列表放在attributes 字段中。
  • 将实例列表直接放在data 字段上,但它返回对象错误或空request.data

我应该如何发送多个对象的数据,这是否可能,我在许多文章中读到只需将many=True 放在序列化程序实例上就足以完成此任务,但我就是无法获得来自请求的数据。

我错过了什么步骤或其他解决方法?

编辑

忘了说两件事

  1. 我正在使用django rest framework json api 库,这可能是数据为空的原因吗?
  2. 我放置了字典,因为我正在测试端点并且我在发送数据时使用 json.dumps(payload)。

【问题讨论】:

  • 为什么不设置` many = isinstance(request.data, list)`?避免冗余代码。

标签: django django-rest-framework


【解决方案1】:

好的,我对创建单个对象实例的工作感到惊讶,因为数据的格式似乎不正确。 当使用 many 参数时,序列化程序需要一个列表,但您发送的是一个 json 对象。

这就是 JSON 的样子:

    [
        {

              "field_1": 1,
              "field_2": 0.05,
              "field_3': "abc"

        },
        {

              "field_1": 1,
              "field_2": 0.05,
              "field_3': "abc"

        },
        {

              "field_1": 1,
              "field_2": 0.05,
              "field_3': "abc"

        }
    ]

这里需要注意以下几点:

  1. JSON 以列表开头
  2. 字段直接在每个对象的主体中 - 没有 type 或 attribute 字段,希望您在序列化程序中实现逻辑来解析它
  3. JSON 不使用单引号,而是使用双引号

您是否检查了request.data 以确认它是空的,如您所说?如果是这样,那么这完全是另一个问题,因为它可能是一个解析问题。

编辑:使用 JSON API

在Rest framework json api github页面稍作挖掘后,我发现this issue请求支持批量操作。 显然,他们在this pull request 中添加了它,您可以在 cmets 中看到多个对象的正确格式。

你的应该是这样的:

{
"data": [
    {
        "type": "MySerializer",
        "attributes": {
            "field_1": 1,
            "field_2": 0.05,
            "field_3": "abc"
        }
    },
    {
        "type": "MySerializer",
        "attributes": {
            "field_1": 1,
            "field_2": 0.05,
            "field_3": "abc"
        }
    },
    {
        "type": "MySerializer",
        "attributes": {
            "field_1": 1,
            "field_2": 0.05,
            "field_3": "abc"
        }
    }
]

}

解析器很可能无法解析您提供的格式的数据,这就是您的request.data 为空的原因。

编辑 2:

虽然批量操作功能尚未集成到 json-api 规范中,但 Django Rest JSON-API 已经为其添加了一个特殊的解析器。 因此,您必须添加此解析器 JSONAPIBulkParser 才能使其正常工作。看看这个comment in the PR

【讨论】:

  • 我确实调试了请求以检查 request.data 属性并且也尝试了您的建议,但是由于我使用django rest framework json api 库“类型”和“属性”是必需的,因为据我所知。
  • 好吧,那是完全不同的故事。所以你确定 request.data 总是空的?这意味着 json api 解析器类无法正确传递它
  • 只有当我尝试发送多个对象时它才为空,当我发送单个实例时,一切都按预期工作。
  • 我已经尝试了您的建议,但数据仍然为空,还检查了上面的两个链接,但根据 drf json api 上的线程,他们似乎仍在等待this pull request 获得批准以便他们将更改应用到库中。
  • @erick.chali PR 在 JSON API 规范中仍然是开放的,但是 django rest json api 已经为它实现了一个解析器。查看github.com/django-json-api/django-rest-framework-json-api/pull/…。你必须使用这个特定的解析器才能工作
猜你喜欢
  • 2021-12-04
  • 2021-08-01
  • 1970-01-01
  • 1970-01-01
  • 2017-09-12
  • 2018-01-08
  • 2018-12-05
  • 2019-09-02
  • 1970-01-01
相关资源
最近更新 更多