pythondjangowebdjango-rest-frameworkhttp-method

Why DRF uses PUT to send files?


I'm trying to understand how file management works in Django Rest Framework, and a question lingers in my mind: Why does Django use PUT to update files? Is it possible to do the same with the PATCH method? How would I be able to push binaries through the patch?

Example of model:

class User(AbstractUser):
    id = HashidAutoField(prefix='user_', primary_key=True)
    picture = models.ImageField(blank=True, null=True, verbose_name=_("profile picture"), storage=PublicMediaStorage(), upload_to=upload_to)

When I try to send using the patch method it only allows me to send in json format, I don't know if there is any way to user PATCH and form-data. For Patch I have something like this:

{
"user": {
        "username": "",
        "first_name": "",
        "password": "",
        "password_confirm": "",
        "email": "",
        "picture": null
    }
}

Solution

  • PUT and PATCH are semantically different (in ideal world, in practice everything goes). PUT replaces data at id, while PATCH partially updates it - only overwritting what changed. Files in general you cannot partially update, so PUT makes sense.

    If you need to support PATCH with formdata you need to at least override partial_update method and maybe Serializer.

    Alternatively (however this is really not a good idea) you can base64 encode image and pass it in json. You will need library drf-base64 or write your own FileField and/or Serializer.

    In short, use PUT for requests that deal with files. In most cases PUT is also simpler to use in DRF than PATCH. Remember that you don't need to provide all fields when using PUT, since you can derive some of them in serializer (for example edit date).