Используйте одну функцию для нескольких полей сериализатора с разными аргументами - PullRequest
0 голосов
/ 11 апреля 2020

У меня есть сериализатор для модели с полем изображения, для которого я сохранил несколько миниатюр изображений разного размера. Я обращаюсь к ним, возвращая их URL с помощью SerializerMethodField:

class GalleryImageSerializer(serializers.ModelSerializer):
    image_sm = serializers.SerializerMethodField()
    image_md = serializers.SerializerMethodField()
    image_lg = serializers.SerializerMethodField()
    image_compressed = serializers.SerializerMethodField()

    def get_image_sm(self, obj):
        return default_storage.url(f'{splitext(obj.image.name)[0]}/sm.jpg')

    def get_image_md(self, obj):
        return default_storage.url(f'{splitext(obj.image.name)[0]}/md.jpg')

    def get_image_lg(self, obj):
        return default_storage.url(f'{splitext(obj.image.name)[0]}/lg.jpg')

    def get_image_compressed(self, obj):
        return default_storage.url(f'{splitext(obj.image.name)[0]}/compressed.jpg')

Этот код работает, но он как бы нарушает принцип "не повторяйся". Как вы можете видеть, это все дубликаты SerializerMethodFields, с единственным отличием в имени файла, например, 'lg.jpg', 'md.jpg', et c.

Я бы предпочел иметь только одна функция, которую я вызываю с аргументом для имени файла, например (псевдокод):

class GalleryImageSerializer(serializers.ModelSerializer):
    image_sm = serializers.SerializerMethodField(filename='sm.jpg')
    image_md = serializers.SerializerMethodField(filename='md.jpg')
    image_lg = serializers.SerializerMethodField(filename='lg.jpg')
    image_compressed = serializers.SerializerMethodField(filename='compressed.jpg')

    def get_image(self, obj, filename=''):
        return default_storage.url(f'{splitext(obj.image.name)[0]}/{filename}')

В настоящее время я не могу найти какой-либо способ добиться этого. Читая исходный код SerializerMethodField, он, кажется, не поддерживает его.

Есть ли способ избежать создания дублирующих функций для полей с произвольными различиями?

1 Ответ

1 голос
/ 12 апреля 2020

Вы можете добавить эти поля в методе to_representation.

def to_representation(self, instance):
    ret = super().to_representation(instance)
    # add img urls to ret dict
    for name in ['sm', 'md', 'lg', 'compressed']:
        ret['image_' + name] = default_storage.url(f'{splitext(instance.image.name)[0]}/{name}.jpg')
    return ret

проверьте документы для более подробной информации: https://www.django-rest-framework.org/api-guide/serializers/#to_representationself -экземпляр

...