Skip to content

Add MaxFileSizeValidator and MinFileSizeValidator for file size constraints #9738

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 2 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
68 changes: 68 additions & 0 deletions docs/api-guide/validators.md
Original file line number Diff line number Diff line change
Expand Up @@ -170,6 +170,74 @@ If you want the date field to be entirely hidden from the user, then use `Hidden

---

## MaxFileSizeValidator and MinFileSizeValidator

These validators can be used to enforce file size constraints on uploaded files. They are especially useful for `FileField` and `ImageField` in serializers.

### MaxFileSizeValidator

Ensures that the uploaded file does not exceed a maximum size (in bytes).

**Parameters:**

* `max_size` (*required*) — The maximum file size in bytes.
* `message` — Custom error message. May use `{max_size}` in the string.
* `code` — Custom error code. Default is `'max_file_size'`.

### MinFileSizeValidator

Ensures that the uploaded file meets a minimum size (in bytes).

**Parameters:**

* `min_size` (*required*) — The minimum file size in bytes.
* `message` — Custom error message. May use `{min_size}` in the string.
* `code` — Custom error code. Default is `'min_file_size'`.

### Usage Examples

#### Basic usage with FileField

from rest_framework import serializers
from rest_framework.validators import MaxFileSizeValidator, MinFileSizeValidator

class FileUploadSerializer(serializers.Serializer):
file = serializers.FileField(validators=[
MaxFileSizeValidator(1024 * 1024), # 1MB max
MinFileSizeValidator(1024), # 1KB min
])

#### Usage with ImageField

class ImageUploadSerializer(serializers.Serializer):
image = serializers.ImageField(validators=[
MaxFileSizeValidator(5 * 1024 * 1024), # 5MB max
MinFileSizeValidator(1024), # 1KB min
])

#### Custom error messages and codes

class CustomFileSerializer(serializers.Serializer):
file = serializers.FileField(validators=[
MaxFileSizeValidator(
max_size=1024 * 1024,
message="File size cannot exceed {max_size} bytes",
code='file_too_large'
),
MinFileSizeValidator(
min_size=1024,
message="File must be at least {min_size} bytes",
code='file_too_small'
),
])

### Error Codes

* `max_file_size` — Default error code for MaxFileSizeValidator
* `min_file_size` — Default error code for MinFileSizeValidator

---

# Advanced field defaults

Validators that are applied across multiple fields in the serializer can sometimes require a field input that should not be provided by the API client, but that *is* available as input to the validator.
Expand Down
71 changes: 71 additions & 0 deletions rest_framework/validators.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
from django.core.exceptions import FieldError
from django.db import DataError
from django.db.models import Exists
from django.utils.deconstruct import deconstructible
from django.utils.translation import gettext_lazy as _

from rest_framework.exceptions import ValidationError
Expand Down Expand Up @@ -344,3 +345,73 @@ def filter_queryset(self, attrs, queryset, field_name, date_field_name):
filter_kwargs[field_name] = value
filter_kwargs['%s__year' % date_field_name] = date.year
return qs_filter(queryset, **filter_kwargs)


@deconstructible
class MaxFileSizeValidator:
"""
Validator that ensures uploaded files do not exceed a maximum size.

Should be applied to individual file fields on the serializer.
"""
message = _('File size must not exceed {max_size} bytes.')
code = 'max_file_size'

def __init__(self, max_size, message=None, code=None):
self.max_size = max_size
self.message = message or self.message
self.code = code or self.code

def __call__(self, value):
if hasattr(value, 'size'):
if value.size > self.max_size:
message = self.message.format(max_size=self.max_size)
raise ValidationError(message, code=self.code)

def __eq__(self, other):
if not isinstance(other, self.__class__):
return NotImplemented
return (self.message == other.message
and self.code == other.code
and self.max_size == other.max_size)

def __repr__(self):
return '<%s(max_size=%s)>' % (
self.__class__.__name__,
smart_repr(self.max_size)
)


@deconstructible
class MinFileSizeValidator:
"""
Validator that ensures uploaded files meet a minimum size.

Should be applied to individual file fields on the serializer.
"""
message = _('File size must be at least {min_size} bytes.')
code = 'min_file_size'

def __init__(self, min_size, message=None, code=None):
self.min_size = min_size
self.message = message or self.message
self.code = code or self.code

def __call__(self, value):
if hasattr(value, 'size'):
if value.size < self.min_size:
message = self.message.format(min_size=self.min_size)
raise ValidationError(message, code=self.code)

def __eq__(self, other):
if not isinstance(other, self.__class__):
return NotImplemented
return (self.message == other.message
and self.code == other.code
and self.min_size == other.min_size)

def __repr__(self):
return '<%s(min_size=%s)>' % (
self.__class__.__name__,
smart_repr(self.min_size)
)
Loading
Loading
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy