Задать вопрос
@from_rugby_to_life

Как закодировать изображение в base64 при загрузке его в БД через админ-панель Джанго?

Мне нужно написать api, при этом у меня уже есть готовый фронтенд. По заданию, у меня есть модель, в которой есть поле ImageField()
class Recipe(models.Model):
    """Модель для управления рецептами
    """

    author = models.ForeignKey(
        User,
        on_delete=models.CASCADE,
        related_name='recipes',
        verbose_name='Автор рецепта',
    )
    name = models.CharField(
        max_length=200,
        verbose_name='Название рецепта',
    )
    image = models.ImageField(
        upload_to='api/images/recipes/',
        verbose_name='Картинка',
    )
    text = models.TextField(
        verbose_name='Описание рецепта',
    )
    ingredients = models.ManyToManyField(
        Ingredient,
        through='IngredientRecipe',
        through_fields=('recipe', 'ingredient'),
        verbose_name='Ингредиенты',
    )
    tags = models.ManyToManyField(
        Tag,
        related_name='recipes',
        verbose_name='Теги',
    )
    cooking_time = models.PositiveIntegerField(
        verbose_name='Время приготовления',
    )
    pub_date = models.DateTimeField(
        verbose_name='Дата публикации',
        auto_now_add=True,
    )

    def __str__(self):
        return f'{self.name}'

    class Meta:
        verbose_name = 'Рецепт'
        verbose_name_plural = 'Рецепты'
        ordering = ['-pub_date',]

По условию, при публикации рецепта фронтенд кодирует картинку в строку base64; на бэкенде её необходимо декодировать и сохранить как файл. Я сделал в сериалайзере для поля image новый класс, в котором переопределил метод to_internal_value:
class ImageConversion(serializers.Field):
    def to_representation(self, value):
        return value

    def to_internal_value(self, data):
        try:
            decode = BytesIO(base64.b64decode(data))
            image = Image.open(decode)
        except ValueError:
            raise serializers.ValidationError(
                'Картинка должна быть кодирована в base64'
            )
        return image

class RecipeSerializer(serializers.ModelSerializer):
    image = ImageConversion()

    class Meta:
        model = Recipe
        fields = ('id', 'author', 'name', 'image', 'text', 'ingredients',
                 'tags', 'cooking_time')

Но в таком виде, когда я загружаю рецепты через админку, и загружаю фото через админку, запросы к api не работают, выпадает вот такая ошибка:
UnicodeDecodeError: 'utf-8' codec can't decode byte 0xff in position 0: invalid start byte

Я так понимаю, это происходит потому, что через админ-панель я загружаю в БД фото, не закодированное в base64, и поэтому, когда сериалайзер пытается декодировать это изображение, то получается вот такая ошибка. Так вот суть вопроса. Если я правильно понимаю суть ошибки, то как тогда можно сделать, чтобы при загрузке фото через админ-панель оно кодировалось в base64? А если я понимаю суть проблемы неправильно, то подскажите, как тогда можно решить эту проблему?
  • Вопрос задан
  • 806 просмотров
Подписаться 1 Средний Комментировать
Пригласить эксперта
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы