Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Clearing a ManyToManyField in a multipart PATCH Request #2883

Open
DavidMuller opened this issue Apr 27, 2015 · 6 comments
Open

Clearing a ManyToManyField in a multipart PATCH Request #2883

DavidMuller opened this issue Apr 27, 2015 · 6 comments

Comments

@DavidMuller
Copy link

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.

@DavidMuller
Copy link
Author

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')

@tomchristie
Copy link
Member

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

@tomchristie tomchristie changed the title Clearing a ManToManyField in a multipart PATCH Request Clearing a ManyToManyField in a multipart PATCH Request May 1, 2015
@guhuajun
Copy link

guhuajun commented Nov 21, 2017

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)

jact added a commit to migasfree/migasfree that referenced this issue Jun 4, 2018
jact added a commit to migasfree/migasfree-backend that referenced this issue Jul 31, 2018
@halfnibble
Copy link

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?

@auvipy
Copy link
Member

auvipy commented Aug 15, 2023

I am open to review an implementation which can implement it properly without any side effect

@guhuajun
Copy link

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 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.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

5 participants