Ошибка переопределения расширений изображений django в моделях

Я хочу получить свою пользовательскую ошибку из validate_image это мой models.py

def validate_image(image):
    valid_image_extensions = ['jpg', 'png', 'jpeg']
    input_extension = str(image).split('.')[1]
    if input_extension not in valid_image_extensions:
        raise ValidationError(
            f"We aren't accepted your extension - {input_extension} only accepted {','.join(valid_image_extensions)}"
        )

class Image(models.Model):
    description = models.CharField(null=True, default='Image', blank=True, max_length=120)
    image = models.ImageField(upload_to='images', validators=[validate_image])

Когда я пытаюсь загрузить изображение с помощью расширения .raw, я ожидаю пользовательской валидации, но у меня ошибка от django.

{
    "image": [
        "File extension “raw” is not allowed. Allowed extensions are: bmp, dib, gif, tif, tiff, jfif, jpe, jpg, jpeg, pbm, pgm, ppm, pnm, png, apng, blp, bufr, cur, pcx, dcx, dds, ps, eps, fit, fits, fli, flc, ftc, ftu, gbr, grib, h5, hdf, jp2, j2k, jpc, jpf, jpx, j2c, icns, ico, im, iim, mpg, mpeg, mpo, msp, palm, pcd, pdf, pxr, psd, bw, rgb, rgba, sgi, ras, tga, icb, vda, vst, webp, wmf, emf, xbm, xpm."
    ]
}

Как я могу запустить пользовательскую валидацию перед валидацией django?

Ваша проблема в том, что ImageField имеет валидатор по умолчанию от PIL, который принимает все расширения PIL, доступные для поля формы.

Вам необходимо создать поле custome для управления вашей проблемой:

from django.core.validators import FileExtensionValidator
from django import forms

def validate_image(image):
    valid_image_extensions = ['jpg', 'png', 'jpeg']
    input_extension = str(image).split('.')[1]
    if input_extension not in valid_image_extensions:
        raise ValidationError(
            f"We aren't accepted your extension - {input_extension} only accepted {','.join(valid_image_extensions)}"
        )

class MyImageField(forms.ImageField):
    default_validators = [validate_image]

class MyModelForm(forms.ModelForm):
    image = MyImageField()

You need to raise a ValidationError in the clean method [Django-doc], not in the validators:
class Image(models.Model):
    # ...
    def clean(self):
        super().clean()
        validate_image(self.image.name)
The validators of a field are called first, and if these succeed, the clean method of the model is called. If this raises a ValidationError, then this will override the validation errors of the field validators.
So by moving the logic to the clean method, you ensure that your custom validation logic runs after the field validators, and thus can override the errors raised in the field validators.
You also might want to use os.path.splitext[pydoc] here to extract the extension, like:
from os.path import splitext

def validate_image(image):
    ext = splitext(image)[1][1:].lower()
    # ...
since str(image).split('.') can result in problems if the filename contains ..

Note: It might be better to use a FileExtensionValidator [Django-doc]
here, and attach that to aFileList of allowed extensions, like:
from django.core.validators import FileExtensionValidator

class Image(models.Model):
    # ...
    image = models.ImageField(
        upload_to='images',
        validators=[FileExtensionValidator(['jpg', 'jpeg', 'png'])]
    )
This will then produce error messages that are "more Django-esque".
Вернуться на верх