Max Image Upload size Validation Django REST API - django

I am using Django and Django Rest Framework. How to validate the image size of the image posted to django rest framework api ?
This is a bit confusing :
FILE_UPLOAD_MAX_MEMORY_SIZE = #something
The maximum size, in bytes, for files that will be uploaded into
memory. Files larger than FILE_UPLOAD_MAX_MEMORY_SIZE will be streamed
to disk. Defaults to 2.5 megabytes.
I set this to 255 and even then I was able to upload a 2MB image from django admin. I want to reject the POST request and raise error if image size is larger than 5MB

FILE_UPLOAD_MAX_MEMORY_SIZE defines the maximum size a file can reach in memory before being streamed to disk. This is an optimization for uploading files. It does not limit the maximum file size that can be uploaded.
While this doesn't answer your question I hope it clears up your confusion about the setting.

Related

Djanog limit image upload size

I am attempting to limit the size of an image that can be uploaded. To do this in the docs I found DATA_UPLOAD_MAX_MEMORY_SIZE I set the value of it to 3mb (3145728 bytes) in my settings.py file but I am still able to upload files larger than 3 mb. I also tried FILE_UPLOAD_MAX_MEMORY_SIZE and the same thing occurred. The only way i can get it to trigger is if i set it to a very low value such as 1 or 2. Any ideas on what I'm doing wrong.
From the docs for DATA_UPLOAD_MAX_MEMORY_SIZE, it does not include uploaded files.
The check is done when accessing request.body or request.POST and is calculated against the total request size excluding any file upload data.
FILE_UPLOAD_MAX_MEMORY_SIZE defines when an uploaded file is saved to the filesystem instead of staying in memory, it does not impose any limits on how large the uploaded file can be
Your best bet is to configure your webserver to limit upload size, client_max_body_size if you are using nginx for example

How to control the size of the image a user can upload

I have a Django app where users can upload images to an S3 bucket, and I tested it with a few users and found out that many uploaded very large photos (up to 55 MB) and when I render the main page, all the images must be displayed. Each time someone browses it, it drains my bandwidth.
Is there a way to limit the size of the image people upload? Perhaps to 10 MB each?
You could do something like this - perhaps in a validators.py:
from django.core.exceptions import ValidationError
def validate_file_size(value):
filesize = value.size
if filesize > 10485760: # 10 MiB in bytes
raise ValidationError("The maximum file size that can be uploaded is 10 MiB")
else:
return value
and then in your models.py:
from .validators import validate_file_size
file = models.FileField(..., validators=[validate_file_size])
However, this is server side, not client side. Therefore, each submission of the file transmits the file over the wire to you, resulting in bandwidth charges. If someone was to upload a 1 GiB file, then the upload would consume 1 GiB of bandwith, even if it is rejected by the server.
Client-side validation would require some JS like this, but you would also need server-side validation.

Django: FILE_UPLOAD_MAX_MEMORY vs DATA_UPLOAD_MAX_MEMORY

I am working with Django 2.2 and got stuck with file upload size validation. I have read django documentation:
DATA_UPLOAD_MAX_MEMORY_SIZE
FILE_UPLOAD_MAX_MEMORY_SIZE
I only set DATA_UPLOAD_MAX_MEMORY (to 20 MB), as mentioned in documentation:
The check is done when accessing request.body or request.POST and is
calculated against the total request size excluding any file upload
data.
But in my project it also checks my uploading file size in request.FILES.
Can someone explain differences between FILE_UPLOAD_MAX_MEMORY and DATA_UPLOAD_MAX_MEMORY? And how to use them properly?
DATA_UPLOAD_MAX_MEMORY
The check is done when accessing request.body or request.POST and is calculated against the total request size excluding any file upload data.
FILE_UPLOAD_MAX_MEMORY_SIZE
The maximum size (in bytes) that an upload will be before it gets streamed to the file system. If uploading files are larger than FILE_UPLOAD_MAX_MEMORY_SIZE, the data of files will be streamed to FILE_UPLOAD_TEMP_DIR
https://docs.djangoproject.com/en/2.2/ref/settings/#file-upload-temp-dir
I don't think you have to set FILE_UPLOAD_MAX_MEMORY_SIZE, because it's the size of memory cache.
FILE_UPLOAD_MAX_MEMORY will load the file contents into the RAM, if the request body or the file which is uploaded is more than FILE_UPLOAD_MAX_MEMORY then the file will be stored in the /tmp directory.
You can restrict the file size in the webserver (Nginx) by adding client_max_body_size 20M;
Here 20 megabytes is the maximum data that request body can have. So if you are uploading a file more than 20 MB, the webserver will not accept it.

Validate file size for multiple files uploads

I have django inline to uploads files, so
it can upload multiple files at same time. (one file for a one file field)
And my nginx limits upload size to 20MB.
Now I want to check the total size of all files, and give proper error massage if it exceeds 20MB before nginx does.
Any helps? please.

Can I upload large images to my server through an HTML form without using RAM?

I am building a site that requires the user to upload images that will be around 70MB each to my server. Currently I am running a Linode with 512MB of RAM. There isn't much extra memory to spare due to other sites being on this server, so is it possible to upload those images to the server without taking up any RAM by dumping the image directly to the filesystem, or does any file uploaded via POST have to be loaded into memory first before it can be dumped to the filesystem? Does the nature of this problem require a server with a lot of RAM?
Would there be a way to somehow integrate an ftp client into an html form? I'm using Django if that makes a difference.
In your project settings, set FILE_UPLOAD_MAX_MEMORY_SIZE to something small (eg 1024 bytes). That will make Django spool request.FILES to disk sooner, not use up RAM
Docs are here if you want more detail: https://docs.djangoproject.com/en/dev/ref/settings/#file-upload-max-memory-size
As per your requirement .... django files upload have two types of uploading.
1 - InMemory Upload
2. Temporary Upload
In case of InMemoryUpload the files you uploaded is in ram only through request.FILES ,
But can set that upload to covert it from InMemoryUpload to TemporaryUpload which ultimately use /tmp folder to store it .. which saves for RAM ...
In settings.py :-
FILE_UPLOAD_MAX_MEMORY_SIZE = #something
The maximum size, in bytes, for files that will be uploaded into memory.
Files larger than FILE_UPLOAD_MAX_MEMORY_SIZE will be streamed to disk.
Defaults to 2.5 megabytes.
FILE_UPLOAD_TEMP_DIR = #to sme path
The directory where uploaded files larger than FILE_UPLOAD_MAX_MEMORY_SIZE will be stored.
Defaults to your system’s standard temporary directory (i.e. /tmp on most Unix-like systems).
Then you can write that file in chunks to your required directory as /tmp deletes all files once system is down.
Follow this link :
https://docs.djangoproject.com/en/dev/topics/http/file-uploads/#changing-upload-handler-behavior