如何使用Django REST框架(DRF)和ModelSerializer将多部分/表单数据保存为QueryDict



我从Next.js API发送多部分/表单数据,我可以按任何方式格式化数据,但我很难获得正确的格式。

目前,我有以下表格数据:

<QueryDict: {
'name': ['Test Product'],
'brands[0]': ['1'],
'brands[1]': ['2'],
'option_types[0]': ['1'],
'product_variants[0]option_values[0]': ['1'],
'product_variants[0]option_values[1]': ['2'],
>

和以下ModelSerializer:

class ProductDetailAdminSerializer(
UniqueFieldsMixin, ProductAdminMixin, WritableNestedModelSerializer
):
categories = PrimaryKeyRelatedField(
many=True, allow_null=True, queryset=Category.objects.all()
)
option_types = PrimaryKeyRelatedField(
many=True, allow_null=True, queryset=OptionType.objects.all()
)
brands = PrimaryKeyRelatedField(
many=True, allow_null=True, queryset=Brand.objects.all()
)
product_variants = ProductVariantDetailAdminSerializer(many=True)
class Meta:
model = Product
fields = (
"pk",
"name",
"subtitle",
"sku_symbol",
"categories",
"brands",
"description",
"option_types",
"product_variants",
)

我的ModelSerializer不接受我指定列表/数组的方式。例如,如果我尝试这样做:

def validate_option_types(self, data):
print(data)
return data

我得到一个空列表,这意味着option_types列表的格式是错误的,product_variantsoption_values也是如此。我只是简单地传递从request.data获得的QueryDict,如下所示:

def create(self, request, *args, **kwargs):
serializer = ProductDetailAdminSerializer(data=request.data)
if serializer.is_valid():
serializer.save()
return JsonResponse(serializer.data)
return JsonResponse(serializer.errors, status=400)

如果我使用上面QueryDict的JSON版本和JSON内容类型,那么序列化程序和其他一切都可以正常工作。顺便说一句,如果我使用ListField而不是PrimaryKeyRelatedField,它也可以按预期工作,尽管ListField实际上并没有给我所需的对象。

因此,总结我的问题,DRF ModelSerializer的正确QueryDict格式(特别是表示列表的字段(是什么?或者,在将QueryDict转换为模型序列化程序所期望的格式时,我是否缺少了一个额外的步骤。

似乎PrimaryKeyRelatedField无法以所需的方式处理多部分/表单数据。这是一个相关的问题。

我的解决方案是将所有非文件形式的数据从前端转换为单个JSON字符串,即

const formData = new FormData();
formData.append('form_data', JSON.stringify(data));

然后在Django中,在我的视图集的create函数中,做一些类似的事情

data = ujson.loads(request.data.get("form_data"))
new_query_dict = QueryDict('', mutable=True)
new_query_dict.update(data)

好的,你不能像你尝试的那样添加多对多类型字段-

首先创建没有多对多字段的对象

obj = MyModal.save()

然后你可以做一些类似的事情-创建和添加多对多字段。

obj.brand.create(name='val1')
obj.option_types.create(name='val2')

您还可以搜索StackOverflow,了解如何将数据添加到ManyToManyFields

相关内容

  • 没有找到相关文章

最新更新