Clearing a ManyToManyField in a multipart PATCH Request
Hello,
I'm having some trouble clearing a ManyToMany field in a multipart PATCH request.
In a JSON request, I would clear my ManyToMany field, 'many_to_many_field' by PATCHing something like:
{"many_to_many_field": []}
However, in a multipart PATCH request, sending values including '[]', '', 'null', 'None', etc all yield the following error:
["Incorrect type. Expected pk value, received unicode."]
It seems that ManyRelatedField.get_value() does not recognize any of those options as special indicators of empty.
I think the crux of this boils down to the fact that there's no way to encode [] in multipart?
from rest_framework.test import APIClient
client = APIClient()
client._encode_data({'foo':[1, 2, 3]}, format='multipart')
('--BoUnDaRyStRiNg\r\nContent-Disposition: form-data; name="foo"\r\n\r\n1\r\n--BoUnDaRyStRiNg\r\nContent-Disposition: form-data; name="foo"\r\n\r\n2\r\n--BoUnDaRyStRiNg--\r\n', u'multipart/form-data; boundary=BoUnDaRyStRiNg; charset=utf-8')
client._encode_data({'foo': []}, format='multipart')
('--BoUnDaRyStRiNg--\r\n', u'multipart/form-data; boundary=BoUnDaRyStRiNg; charset=utf-8')
I think the crux of this boils down to the fact that there's no way to encode [] in multipart?
Correct. This is a constraint of HTML form input. We can either document this, or instead simply not display (or disable with a tooltip) the PATCH button for form input, and only enable it for raw JSON input.
See also #2894
My workaround is listed below. Hope we will have a nice solution later.
Using null when firing an ajax request.
if (subscribersList.select2('data').length === 0) {
data.push({"name": "subscribers", "value": null})
}
Add some code to clear ManyToManyField in is_valid method
def is_valid(self, raise_exception=False):
data = self.get_initial()
if data.get('subscribers')[0] == '':
self.instance.subscribers.clear()
del self.fields['subscribers']
return super().is_valid(raise_exception)
This comment from 2017 just saved my sanity.
Would it be something to consider, making this a supported solution?
I.e. We allow "None" with allow_null=True, so why not allow "[]" or "None" in a ManyToMany html submit?
I am open to review an implementation which can implement it properly without any side effect
This comment from 2017 just saved my sanity. Would it be something to consider, making this a supported solution? I.e. We allow
"None"withallow_null=True, so why not allow"[]"or"None"in a ManyToMany html submit?
I have totally no idea for what I was doing at that moment. :) It's glad to see the snippet can help you a little bit. Nowadays, I am just using Starlette + Vue (and Naive UI) if I need to create some demos.