I am sending multipart/formdata from a Next.js API and I can format the data whichever way I want but I am struggling to get the right format.
For now, I have the following formdata:
<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'],
>
and the following 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",
)
My ModelSerializer is not accepting the way I am specifying the lists/arrays. For instance, if I try to do:
def validate_option_types(self, data):
print(data)
return data
I get an empty list meaning the format for option_types
list is wrong and the same applies for the product_variants
and option_values
. I am simply passing the QueryDict obtained from request.data
as follows:
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)
The serializer and everything else are working fine if I use a JSON version of the QueryDict above and the JSON content-type. Incidentally, if I use ListField
instead of PrimaryKeyRelatedField
it also works as expected although, ListField
doesn't actually give me the objects required.
So to summarise my question, what is the correct QueryDict format (specifically for fields which represent lists) for the DRF ModelSerializer? Or is there an extra step that I am missing in getting the QueryDict to the format expected by the model serializer.
CodePudding user response:
ok, You can not add many-to-many type field as the way you are trying to -
first create the object without many to many fields
obj = MyModal.save()
and then you can do something like - to create and add your many to many fields.
obj.brand.create(name='val1')
obj.option_types.create(name='val2')
You can also search StackOverflow on how to add data to ManyToManyFields
CodePudding user response:
Seems like PrimaryKeyRelatedField
can't process multipart/formdata in the desired way. Here's a related question.
My solution has been to convert all the non-file form data into a single JSON string from the front-end i.e.
const formData = new FormData();
formData.append('form_data', JSON.stringify(data));
and then in Django, in the create
function of my viewset, do something like
data = ujson.loads(request.data.get("form_data"))
new_query_dict = QueryDict('', mutable=True)
new_query_dict.update(data)