Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to serialize(JSON) FileField in Django

I am new to Django and trying to build an app to test out few things for my project. I want to read the form - do some validation and then send the input to another module (say a scheduler running separately). The scheduler rest api will be called with the form data (which is file) and the scheduler will load the data into the models. I am using python requests and serializing data into json before calling the rest api. This is where I am getting error. Django on request.FILES create a InMemoryUploadedFile class which has the data loaded somewhere in memory and serializing this to Json is not straightforward. I tried looking other ways (like image serializers example) but not able to resolve this issue.

forms.py

class UploadDatasetForm(forms.Form):
    docfile = forms.FileField(label='Choose file')

views.py

def test_upload(request):
    if request.method == 'POST':
        form = UploadDatasetForm(request.POST, request.FILES)
        if form.is_valid():
            in_file = request.FILES['docfile']
            payload = {'doc_file': in_file}
            msg = json.dumps(payload)
            URL = 'http://localhost:8880/form'
            r = requests.post(URL, data=msg)
    return HttpResponse(json.dumps(r.text), content_type="application/json")

Error:

raise TypeError(repr(o) + " is not JSON serializable")
TypeError: <InMemoryUploadedFile: A_test.csv (text/csv)> is not JSON serializable

Any help here will be appreciated. Thanks a lot.

like image 960
yguw Avatar asked Jul 11 '17 21:07

yguw


People also ask

How do I serialize Queryset?

To serialize a queryset or list of objects instead of a single object instance, you should pass the many=True flag when instantiating the serializer. You can then pass a queryset or list of objects to be serialized.

How do you serialize a JSON string in Python?

The json module exposes two methods for serializing Python objects into JSON format. dump() will write Python data to a file-like object. We use this when we want to serialize our Python data to an external JSON file. dumps() will write Python data to a string in JSON format.

What is JSON serialization in python?

Serialization is the process of transforming objects of complex data types (custom-defined classes, object-relational mappers, datetime, etc.) to native data types so that they can then be easily converted to JSON notation.


2 Answers

By default python only supports of converting a hand full of default datatypes (str, int, float, dict, list, etc.). You try to convert InMemoryUploadedFile, the dumps function doesn't know how to handle that. What you need to do is provide a method to convert the data into one of the data types that python does supports.

class MyJsonEncoder(DjangoJSONEncoder):
    def default(self, o):
        if isinstance(o, InMemoryUploadedFile):
           return o.read()
        return str(o)


msg = json.dumps(payload, cls=MyJsonEncoder)
like image 43
Du D. Avatar answered Oct 24 '22 02:10

Du D.


It looks like you're trying to serialize a reference to an InMemoryUploadedFile instance - if you just want to JSON serialize the data and not the whole class instance you could read the data.

Replace:

payload = {'doc_file': in_file}

With

payload = {'doc_file': in_file.read()}

You'll want be sure to use chunks() if the data is large: https://docs.djangoproject.com/en/1.11/ref/files/uploads/#django.core.files.uploadedfile.UploadedFile.chunks

like image 113
zephiyr Avatar answered Oct 24 '22 02:10

zephiyr