toastdriven/django-tastypie — pull request #606 by philipn (2012-08-09 00:08:09+00:00)
Title: File uploads

This branch implements file upload support using multipart/form-data. Has tests. Tested with Django 1.3.1 and Django 1.4.1. Based on the discussion on #42.

------

Not sure where to put this, but here's a note about how this works:

A multipart/form-data request looks like this:

```
--221b0b9610b04bd1a914d6fbb703a900
Content-Disposition: form-data; name="something"
Content-Type: text/plain

golden gate park
--221b0b9610b04bd1a914d6fbb703a900
Content-Disposition: form-data; name="file"; filename="/home/philip/out.txt"
Content-Type: text/plain

hellothere

--221b0b9610b04bd1a914d6fbb703a900
Content-Disposition: form-data; name="somethingelse"
Content-Type: text/plain

hithere sup
--221b0b9610b04bd1a914d6fbb703a900--
```

Django takes the fields with Content-Disposition: ... ; filename="..." and puts them into Django's request.FILES dictionary. The other fields are put into request.POST.

This presents a bit of a problem because, with multipart/form-data, each piece of the response has to have a `name`. It has to be a form. So we have to do something more complex than simply deserialize `raw_post_data`.

One downside here is that there's no way we could support creating a file in a nested resource in a single POST/PUT. Or nested relations in general. One workaround may be to allow the form key to carry Content-Type: application/json and contain a JSON string rather than a form valid, but that too may be confusing because we would have something like:

(form keys):

```
[ filekey ] --> file content
[ resource_field ] --> "{'some':'json', 'goes':'here'}"
```

which would create, on the server side, something like:

```
{'filekey': ,
'resource_field':
{'some': 'json',
'goes': 'here'}
}
```

which is confusing because of the two ways objects are created -- as text values in form fields and as serialized strings in form field values.

So the only thing to do, at least for now, is to do what Michael Wu does in 4e1c642cd660530edbbf529846269112b45d582e - treat the form as a flat dictionary.