Skip to content

Django File Upload Image Validate Fix

DodaTech Updated 2026-06-24 2 min read

In this tutorial, you'll learn about Django File Upload Image Validate Fix. We cover key concepts, practical examples, and best practices.

The Problem

Users upload non-image files to ImageField, or upload huge images that crash the server. Without validation, you get corrupted data, disk overflow, or HTML files posing as images (XSS risk).

Quick Fix

Wrong — no validation on ImageField

class Profile(models.Model):
    avatar = models.ImageField(upload_to='avatars/')

Output: Any file can be uploaded as avatar. 100MB photos crash the server. JavaScript files can be renamed as .png and uploaded.

Correct — custom image validator

from django.core.exceptions import ValidationError
from django.core.validators import FileExtensionValidator
from PIL import Image
import os

def validate_image(image):
    max_size_mb = 5
    max_width = 2048
    max_height = 2048

    if image.size > max_size_mb * 1024 * 1024:
        raise ValidationError(f"Max file size is {max_size_mb}MB")

    try:
        img = Image.open(image)
        width, height = img.size
        if width > max_width or height > max_height:
            raise ValidationError(f"Max dimensions: {max_width}x{max_height}px")
        img.verify()  # Verify it's a valid image
    except Exception:
        raise ValidationError("Invalid image file")

class Profile(models.Model):
    avatar = models.ImageField(
        upload_to='avatars/',
        validators=[validate_image, FileExtensionValidator(['jpg', 'jpeg', 'png', 'webp'])],
        help_text="Max 5MB, max 2048x2048px"
    )

Rejecting by content type (not just extension)

import magic

def validate_image_content(image):
    mime = magic.from_buffer(image.read(1024), mime=True)
    image.seek(0)
    allowed = ['image/jpeg', 'image/png', 'image/webp']
    if mime not in allowed:
        raise ValidationError(f"Invalid image type: {mime}")

Serializer-level validation (DRF)

from rest_framework import serializers

class AvatarSerializer(serializers.Serializer):
    avatar = serializers.ImageField()

    def validate_avatar(self, value):
        if value.size > 5 * 1024 * 1024:
            raise serializers.ValidationError("Max 5MB")
        if value.content_type not in ['image/jpeg', 'image/png']:
            raise serializers.ValidationError("JPEG or PNG only")
        return value

Thumbnail generation on upload

from django.db.models.signals import post_save
from PIL import Image

@receiver(post_save, sender=Profile)
def create_thumbnail(sender, instance, **kwargs):
    if instance.avatar and not instance.thumbnail:
        img = Image.open(instance.avatar.path)
        img.thumbnail((200, 200))
        thumb_path = instance.avatar.path.replace('avatars/', 'thumbs/')
        os.makedirs(os.path.dirname(thumb_path), exist_ok=True)
        img.save(thumb_path)

Prevention

  • Always validate file size, dimensions, and content type on ImageField.
  • Use FileExtensionValidator plus content-type sniffing.
  • Resize large images on upload to prevent storage waste.

Common Mistakes with file upload image validate

  1. Misunderstanding that String is [Char] with poor performance for large text operations
  2. Using foldl instead of foldl' causing stack overflow on large lists
  3. Forgetting deriving (Show, Eq) on custom data types needed for debugging

These mistakes appear frequently in real-world DJANGO code. DodaTech's contributors have identified these patterns through analysis of open-source projects and production systems.

Practice Exercise

Write a pure function that safely divides two integers using Maybe, then test it with edge cases like division by zero and negative numbers.

This exercise reinforces the concepts covered in this guide. Try implementing it before checking online solutions.

FAQ

### What's the difference between validating extension vs content type?

Extensions are easily spoofed (rename .exe to .png). Content-type validation reads the actual file header and is more secure.

How do I handle existing oversized images?

Run a management command that resizes or rejects images older than a certain date. Or add validation on access.

What library checks MIME types?

python-magic or file command. PIL can verify image integrity but is not a security boundary for content type.

Built by the developers of DodaTech

Doda Browser, DodaZIP & Durga Antivirus Pro