Howto make upload form and process image in Django

Hi everyone,
i will show you how to create upload form to upload the file, we will generate a thumbnail and show it on the website. To generate thumbnails I will use popular module Pillow.

# the content add to your urls.py

urlpatterns += [path('upload-form/', uploadapp.views.upload, name="upload")]

I will create a model of an upload form. The method clean_user_file() check if the upload file size is at most 5 MB and the file is a picture, i.e. has the correct extension (e.g. jpg, png, gif or jpeg).

from django import forms
from pathlib import Path

class UserForm(forms.Form):
    user_file = forms.FileField()

    def clean_user_file(self, *args, **kwargs):
        cleaned_data = super(UserForm,self).clean()
        user_file = cleaned_data.get("user_file")

        if user_file:
            if user_file.size > 5 * 1024 * 1024:
                raise forms.ValidationError("File is too big.")

            if not Path(user_file).suffix.strip().lower() in ['.jpg','.png','.gif','.jpeg']:
                raise forms.ValidationError("File does not look like as picture.")

        return user_file

The method upload() generates a thumbnail and applies resize and sharpness effect.
The original image and thumbnail will save to disk directory MEDIA_ROOT.

# the snippet code of the method upload()

from PIL import Image as PILImg
from PIL import ImageEnhance as PILImageEnhance
from pathlib import Path
from django.conf import settings
from uploadapp.forms import UserForm

def upload(request):
    template = "upload.html"
    data = {}

    if request.POST:
        userform = UserForm(request.POST, request.FILES)

        if userform.is_valid():
            origin_form = userform.cleaned_data["user_file"]
            origin_name = origin_form.name

            original_file = Path(settings.MEDIA_ROOT).joinpath(origin_name)
            thumb_name = original_file.stem + "_thumb.jpg"
            thumb_file = Path(settings.MEDIA_ROOT).joinpath(thumb_name)

            if original_file.is_file():
                original_file.unlink()

            if thumb_file.is_file():
                thumb_file.unlink()

            with open(original_file, 'wb+') as f:
                f.write(origin_form.read())

            origin_form.seek(0)

            # resize image
            image = PILImg.open(origin_form)
            image = image.resize((150, 150), PILImg.ANTIALIAS)
            # sharpness image
            image = PILImageEnhance.Sharpness(image)
            image = image.enhance(1.3)

            image.save(thumb_file, 'JPEG')

            data.update(origin_name=origin_name)
            data.update(thumb_name=thumb_name)

            userform = UserForm()

    else:

        userform = UserForm()

    data.update(userform=userform)

    return render(request, template, data)

I will create a template upload.html to show the original image and the thumbnail.

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="utf-8">
</head>
<body>

<div style="margin: 0 auto; width: 990px">

    <form method="post" action="upload-form/" enctype="multipart/form-data">
        {% csrf_token %}
        {{ userform.as_p }}
        <input type="submit">
    </form>

    <br>
    <br>

    <h2>{{ origin_name }} (original)</h2>

    {% if origin_name %}
        <img src="{{ MEDIA_URL }}{{ origin_name }}">
    {% endif %}

    <br>
    <br>

     <h2>{{ thumb_name }} (150x150)</h2>

    {% if thumb_name %}
        <img src="{{ MEDIA_URL }}{{ thumb_name }}">
    {% endif %}

</div>

</body>
</html>

That is all and as always, any improvement ideas are welcomed.

Enjoy!
Hanz