Django Rest Framework разный размер изображения для разных уровней учетной записи (базовый, премиум)

Существует три уровня учетной записи bultin: Basic, Premium и Enterprise: Пользователи тарифного плана «Базовый» после загрузки изображения получают:

  • ссылка на миниатюру высотой 200 пикселей Пользователи тарифного плана «Премиум» получают:
  • ссылка на миниатюру высотой 200 пикселей
  • ссылка на миниатюру высотой 400 пикселей
  • ссылка на изначально загруженное изображение

Я понятия не имею, как я могу совместить возможность сохранять разные разрешения фотографий, добавленных пользователем, в зависимости от их членства. Мое решение сохраняет одно разрешение для всех пользователей.

модели.py

from django.db import models
from django.utils import timezone
from django.contrib.auth.models import User
from PIL import Image


def user_directory_path(instance, filename):
    return 'images/{0}'.format(filename)


class Images(models.Model):

    title = models.CharField(max_length=250)
    image = models.ImageField(upload_to=user_directory_path)
    created = models.DateTimeField(default=timezone.now)
    author = models.ForeignKey(User, on_delete=models.PROTECT, related_name='author')

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

        img = Image.open(self.image.path)

        if img.height > 200:
            output_size = (200, 200)
            img.thumbnail(output_size)
            img.save(self.image.path)


class Profile(models.Model):

    MEMBERSHIP = (
        ('BASIC', 'Basic'),
        ('PREMIUM', 'Premium'),
        ('ENTERPRISE', 'Enterprise')
    )

    user = models.OneToOneField(User, on_delete=models.CASCADE)
    membership = models.CharField(max_length=10, choices=MEMBERSHIP, default='BASIC')

    def __str__(self):
        return f'{self.user.username} {self.membership} Profile'

сериализаторы.py

from rest_framework import serializers
from blog.models import Images, Profile



class ImagesSerializer(serializers.ModelSerializer):

    class Meta:
        model = Images
        fields = ('author', 'title', 'image')


просмотры.py

class ImagesViewSet(viewsets.ModelViewSet):

    queryset = Images.objects.all()
    serializer_class = ImagesSerializer

    def get_queryset(self):

        user = self.request.user
        return Images.objects.filter(author=user)

Почему в Python есть оператор "pass"?
Почему в Python есть оператор "pass"?
Оператор pass в Python - это простая концепция, которую могут быстро освоить даже новички без опыта программирования.
Некоторые методы, о которых вы не знали, что они существуют в Python
Некоторые методы, о которых вы не знали, что они существуют в Python
Python - самый известный и самый простой в изучении язык в наши дни. Имея широкий спектр применения в области машинного обучения, Data Science,...
Основы Python Часть I
Основы Python Часть I
Вы когда-нибудь задумывались, почему в программах на Python вы видите приведенный ниже код?
LeetCode - 1579. Удаление максимального числа ребер для сохранения полной проходимости графа
LeetCode - 1579. Удаление максимального числа ребер для сохранения полной проходимости графа
Алиса и Боб имеют неориентированный граф из n узлов и трех типов ребер:
Оптимизация кода с помощью тернарного оператора Python
Оптимизация кода с помощью тернарного оператора Python
И последнее, что мы хотели бы показать вам, прежде чем двигаться дальше, это
Советы по эффективной веб-разработке с помощью Python
Советы по эффективной веб-разработке с помощью Python
Как веб-разработчик, Python может стать мощным инструментом для создания эффективных и масштабируемых веб-приложений.
0
0
108
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Я думаю, вам нужно расширить свою модель и сохранить изображения в базе данных во всех разрешениях:

# models.py
class Images(models.Model):

    title = models.CharField(max_length=250)
    image = models.ImageField(upload_to=user_directory_path)
    image_200 = models.ImageField(upload_to=user_directory_path_200)
    image_400 = models.ImageField(upload_to=user_directory_path_200)
    
    def save(self, *args, **kwargs):
        super().save(*args, **kwargs)

        img_200 = Image.open(self.image.path)
        img_400 = Image.open(self.image.path)

        output_size_200 = (200, 200)
        output_size_400 = (400, 400)
        img_200.thumbnail(output_size_200)
        img_400.thumbnail(output_size_400)
        img_200.save(self.image_200.path)
        img_400.save(self.image_400.path)

Затем нужно добавить сериализацию в зависимости от привилегий пользователя, примерно так:

# serializers.py
class ImagesBasicUserSerializer(serializers.ModelSerializer):

    class Meta:
        model = Images
        fields = ('author', 'title', 'image_200')


class ImagesPremiumUserSerializer(serializers.ModelSerializer):

    class Meta:
        model = Images
        fields = ('author', 'title', 'image_200', 'image_400', 'image')

А затем сериализовать данные в зависимости от привилегий пользователя, переопределив метод get_serializer_class по подобию этого:

# views.py
class ImagesViewSet(viewsets.ModelViewSet):

    queryset = Images.objects.none()
    serializer_class = ImagesBasicUserSerializer
    
    def get_user(self):
        
        user = self.request.user
        return user

    def get_serializer_class(self):
        
        user = self.get_user()
        if user.membership == 'Basic':
            return ImagesBasicUserSerializer
        if user.membership == 'Premium':
            return ImagesPremiumUserSerializer
    
    def get_queryset(self):

        user = self.get_user()
        return Images.objects.filter(author=user)

Другие вопросы по теме