@NyxDeveloper

DRF, как сериализовать объект по разному, в зависимости от метода?

Уважаемые жители тостера, я столкнулся с проблемой, решение которой никак не могу найти в официальной документации DRF. Необходимо отдавать JSON в читаемом виде, при запросе списка, и в обычном для DRF виде, при запросе конкретного объекта. То есть, при вызове метода list() - вместо первичных ключей должны выводиться нужные поля, а при вызове retrive() - должны выводиться pk. Можно ли реализовать это стандартными способами и не городить велосипеды?
  • Вопрос задан
  • 280 просмотров
Пригласить эксперта
Ответы на вопрос 2
@NyxDeveloper Автор вопроса
В общем, мне в голову пришла только идея отделить строковые представления от привычных pk с помощью нижнего подчеркивания. Теперь я дублирую поля, которые нужно отдавать в строковом состоянии и пишу их названия, начиная с нижнего подчеркивания.
serializers.py
class ProjectSerializer(ModelSerializer):
    _counterparty = serializers.SlugRelatedField(many=False, read_only=True, slug_field='short_name',
                                                 source='counterparty')
    _participant = serializers.SlugRelatedField(many=False, read_only=True, slug_field='short_name',
                                                source='participant')
    _project_type = serializers.SlugRelatedField(many=False, read_only=True, slug_field='title',
                                                 source='project_type')
    _status = serializers.SlugRelatedField(many=False, read_only=True, slug_field='title', source='status')
    _funding_source = serializers.SlugRelatedField(many=False, read_only=True, slug_field='title',
                                                   source='funding_source')
    _quarter = serializers.SlugRelatedField(many=False, read_only=True, slug_field='title', source='quarter')

    _team = serializers.SlugRelatedField(many=False, read_only=True, slug_field='title', source='team')

    _employee_init = serializers.StringRelatedField(many=False, read_only=True, source='employee_init')

    class Meta:
        model = Project
        fields = '__all__'


json
[
    {
        "id": 1,
        "_counterparty": "ООО \"Локалхост\"",
        "_participant": "Участник 1",
        "_project_type": "Стройка",
        "_status": "Активный",
        "_funding_source": "Собственный бюджет",
        "_quarter": "Первый I",
        "_team": "Бригада 345",
        "_employee_init": "Сотрудник Сотрудник Сотрудник",
        "title": "первый проект",
        "amount_planned": 132456.0,
        "implementation": 2021,
        "date_contract": "2021-04-02",
        "date_delivery_contract": "2021-04-02",
        "date_gk_contract": "2021-04-08",
        "date_delivery": "2021-04-23",
        "date_commissioning": "2021-04-24",
        "approved": true,
        "is_archive": false,
        "counterparty": 1,
        "participant": 1,
        "project_type": 1,
        "status": 1,
        "funding_source": 1,
        "quarter": 1,
        "team": 1,
        "employee_init": 1
    }
]


Несмотря на это мне кажется, что я придумал ужасный костыловелик и есть способ получше, по этому прошу поделиться своими способами решения данной проблемы.
Ответ написан
Комментировать
@reqww
Можно проще, в __init__ сериализатора вытащить запрос, который лежит тут self.context["request"]
Из запроса вытаскиваешь метод и начинаешь приюавлять к переменной seld.fields поля
Пример:
class SomeSerializer(serializers.Serializer):
   def __init__(self):
        super().__init__()
        request = self.context["request"]
        if request.method == "GET":
             self.fields += serializers.IntegerField(read_only=True)
        else: 
         ....

Мог напутать с сигнатурой, но концепция такова
Ответ написан
Комментировать
Ваш ответ на вопрос

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

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