Search code examples
djangogoogle-app-enginemultipartform-datadjango-nonrel

Foreign character breaking when posted via multipart/form-data


I am using django-nonrel on the google-app-engine.

When I'm posting a foreign character,

in my case Korean Character, with a multipart/form-data it is breaking.

<form method="post" enctype="multipart/form-data" action=".">

For example, if I post a string '한글'

it is recorded in my database as a string '7ZWc6riA'.

From my research this is the common case in jsp,

and in Java it's solve as below:

String name = multipartRequest.getParameter("name");
name = new String(name.getBytes("8859_1"),"utf-8");

However, I was unable to find the equivalent in Django,

nor not quite sure if I can solve my problem with the same logic.

Any help/clue will be appreciated.


Solution

  • I found an open issue for this problem.

    Issue 2749: Blobstore handler breaking data encoding http://code.google.com/p/googleappengine/issues/detail?id=2749

    You can find several different options to go around this bug in the link above.

    Personally, as a Django-nonrel user, I'd go with a solution shown below:

    import logging
    import quopri
    log = logging.getLogger(__name__)
    
        class BlobRedirectFixMiddleware(object):
            def process_request(self, request):
                if request.method == 'POST' and 'HTTP_X_APPENGINE_BLOBUPLOAD' in request.META and request.META['HTTP_X_APPENGINE_BLOBUPLOAD'] == 'true':
                    request.POST = request.POST.copy()
                    log.info('POST before decoding: %s' % request.POST)
                    for key in request.POST:
                        if key.startswith('_') or key == u'csrfmiddlewaretoken':
                            continue
                        value = request.POST[key]
                        if isinstance(value,(str, unicode)):
                            request.POST[key] = unicode(quopri.decodestring(value), 'iso_8859-2')
                    log.info('POST after decoding: %s' % request.POST) 
                return None