简体   繁体   中英

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.

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

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)

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM