django-parler-rest
django-parler-rest copied to clipboard
"Input is not a valid dict" when posting to a model with file attribute
Hello I've just detected that we get the error :
"Input is not a valid dict"
when posting with requests.post with a files attribute.
the file attribute will force the request as a multipart formencoded, so the data will be json stringified.
I've created a pull request for handling this behavior. https://github.com/django-parler/django-parler-rest/pull/20
Thanks for the PR! As mentioned in #20, do you have an example how to cause this error? For example, a curl command or Django unit test?
Yes I was using a curl command like:
curl -H "Content-Type:multipart/form-data" -F translations="{\"en\": {\"display_name\": \"toto\"}}" -F name="test" -F type="3" -F "file=@./toto;type=application/json" http://my_domain.com/my_ressource/
Hi. This issue still exists - is there any update regarding this error?
What I did to make it work was using json.loads(data) to format the submitted form data. Unfortunately django-parler is checking for isinstance(data, dict) (line 128, here) which returns false on JavaScript objects that where submitted by form data and previous stringified with json.stringify.
Hope this helps someone.
Really helpful @crstian . I had the same issue and solved quickly with your solution !
I have added the change that was done by @GuillaumeCisco but the code doesn't appear to work: Is there anything I am doing wrong?
...
if isinstance(data, str):
# try to convert to json
try:
data = json.loads(data)
except:
self.fail('invalid_json_dump')
...
You should overload TranslatedFieldsField and call the overloaded class in your serializer like this:
import json
from parler_rest.fields import TranslatedFieldsField
from rest_framework import serializers
class TranslatedFieldFixed(TranslatedFieldsField):
def to_internal_value(self, data):
"""
Deserialize data from translations fields.
For each received language, delegate validation logic to
the translation model serializer.
"""
if data is None:
return
data = json.loads(data)
if not isinstance(data, dict):
self.fail('invalid')
if not self.allow_empty and len(data) == 0:
self.fail('empty')
result, errors = {}, {}
for lang_code, model_fields in data.items():
serializer = self.serializer_class(data=model_fields)
if serializer.is_valid():
result[lang_code] = serializer.validated_data
else:
errors[lang_code] = serializer.errors
if errors:
raise serializers.ValidationError(errors)
return result
But It would be best if the error is fixed directly in the library