Skip to content

Instantly share code, notes, and snippets.

@devwaseem
Last active July 16, 2025 13:38
Show Gist options
  • Select an option

  • Save devwaseem/d0d0401a94d36d344669685714ee40ff to your computer and use it in GitHub Desktop.

Select an option

Save devwaseem/d0d0401a94d36d344669685714ee40ff to your computer and use it in GitHub Desktop.
Django validator for file size and content
from typing import Iterable
import magic
from django.core.exceptions import ValidationError
from django.core.files.base import File
from django.template.defaultfilters import filesizeformat
from django.utils.deconstruct import deconstructible
@deconstructible
class FileValidator:
error_messages = {
"max_size": (
"Ensure this file size is not greater than %(max_size)s."
" Your file size is %(size)s."
),
"min_size": (
"Ensure this file size is not less than %(min_size)s. "
"Your file size is %(size)s."
),
"content_type": "Files of type %(content_type)s are not supported.",
}
def __init__(
self,
max_size: int | None = None,
min_size: int | None = None,
content_types: Iterable[str] | None = None,
) -> None:
self.max_size = max_size
self.min_size = min_size
self.content_types = content_types
def __call__(self, data: File) -> None:
if self.max_size is not None and data.size > self.max_size:
params = {
"max_size": filesizeformat(self.max_size),
"size": filesizeformat(data.size),
}
raise ValidationError(
message=self.error_messages["max_size"],
code="max_size",
params=params,
)
if self.min_size is not None and data.size < self.min_size:
params = {
"min_size": filesizeformat(self.min_size),
"size": filesizeformat(data.size),
}
raise ValidationError(
message=self.error_messages["min_size"],
code="min_size",
params=params,
)
if self.content_types:
content_type = magic.from_buffer(data.read(), mime=True)
data.seek(0)
if content_type not in self.content_types:
params = {"content_type": content_type}
raise ValidationError(
message=self.error_messages["content_type"],
code="content_type",
params=params,
)
def __eq__(self, other: object) -> bool:
return (
isinstance(other, FileValidator)
and self.max_size == other.max_size
and self.min_size == other.min_size
and self.content_types == other.content_types
)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment