Process the image on the website using Pilgram

I'm completely zero in programming and I'm just trying to take the first steps. I think the solution to my problem is pretty simple, but I can't find it. I want to have 2 fields in the Images model: image and processed_image.

I am using Django 5.1.4, Python 3.13.1, Pillow 11.1.0 and Pilgram 1.2.1

I want the user to upload an image to a form on the website. The image was processed using pilgram. And then the processed image was saved in the processed_image field. But when I save the picture, the processed_image field in the database remains empty. Please tell me what my mistake is?

postcard/images/models.py

from django.db import models
from PIL import Image
import pilgram
import os
from django.urls import reverse
from django.contrib.auth.models import User

from .services.utils import unique_slugify


class Images(models.Model):
    user = models.ForeignKey(User, on_delete=models.CASCADE, related_name='user')
    title = models.CharField('Название', max_length=255)
    slug = models.SlugField("URL", max_length=255, unique=True, db_index=True)
    image = models.ImageField('Изображение', upload_to="images/%Y/%m/%d/")
    processed_image = models.ImageField('Отработанное изображение', upload_to="processed/%Y/%m/%d/", blank=True, null=True)
    time_create = models.DateTimeField('Дата создания', auto_now_add="True")


    def __str__(self):
        return self.title


    def save(self, *args, **kwargs):
        super().save(*args, **kwargs)

        if self.image:
            self.process_image()

    def process_image(self):
        img_path = self.image.path
        img = Image.open(img_path)

        img = pilgram._1977(img)

        processed_path = os.path.join(os.path.dirname(img_path),f"processed_{os.path.basename(img_path)}")
        img.save(processed_path)

        self.processed_image = processed_path
        super().save(update_fields=['processed_image'])

    class Meta:
        verbose_name = 'Картинка'
        verbose_name_plural = 'Картинки'
        ordering = ['-time_create', 'title']

    def get_absolute_url(self):
        return reverse('image', kwargs={'image_slug': self.slug})

    def save(self, *args, **kwargs):
        """
        Сохранение полей модели при их отсутствии заполнения
        """
        if not self.slug:
            self.slug = unique_slugify(self, self.title)
        super().save(*args, **kwargs)

postcard/images/views.py

from django.shortcuts import render, redirect
from django.urls import reverse_lazy
from django.views.generic import ListView, DetailView, CreateView, UpdateView, DeleteView
from .forms import ImageForm
from .models import Images

class ImagesList(ListView):
    paginate_by = 20
    model = Images
    template_name = 'images/image_list.html'
    context_object_name = 'images'

class UploadImage(CreateView):
    form_class = ImageForm
    template_name = 'images/upload.html'
    success_url = reverse_lazy('upload_image')

    def form_valid(self, form):
        form.instance.user = self.request.user
        return super(UploadImage, self).form_valid(form)

class ImageDone(DetailView):
    model = Images
    template_name = 'images/image_done.html'
    slug_url_kwarg = 'image_slug'
    context_object_name = 'image'

postcard/images/forms.py

from django import forms
from .models import *

class ImageForm(forms.ModelForm):
    class Meta:
        model = Images
        fields = ['title', 'image']

postcard/images/urls.py

from django.urls import path
from .views import *

urlpatterns = [
    path('upload_image', UploadImage.as_view(), name='upload_image'),
    path('image/<slug:image_slug>/', ImageDone.as_view(), name='image'),
    path('image_list', ImagesList.as_view(), name='image_list'),
]

postcard/images/admin.py

from django.contrib import admin
from .models import Images

@admin.register(Images)
class ImagesAdmin(admin.ModelAdmin):
    prepopulated_fields = {'slug': ('title',)}
Вернуться на верх