Django REST Framework: пользовательские переменные сериализатора - PullRequest
0 голосов
/ 01 апреля 2020

Я использую сериализатор модели (многие = True) в Django Rest Framework, где я хочу вернуть свойства booking_color и text_color в JSON, чтобы отобразить экземпляр бронирования в плагине календаря. Оба свойства зависят от вычисляемых переменных job_type и job_status (с использованием внешних ключей и т. Д. c.). Я хочу выполнить вычисление для этих переменных, когда конкретный экземпляр инициализируется (в методе init), чтобы оба вычисленных значения стали доступны для обоих полей метода (booking_color и text_color). Метод init, однако, передает весь набор запросов как «inst», и поэтому я не могу выполнить вычисления, специфичные для экземпляра c. Что было бы лучшим способом обойти это? Ранее я выполнял эти вычисления в первом методе в списке (в данном случае «get_booking_color»), и он работает, но он не очень элегантен, и я не уверен, что должен это делать.

class CalendarView(serializers.ModelSerializer):
    booking_color = serializers.SerializerMethodField()
    text_color = serializers.SerializerMethodField()

    def __init__(self, inst):
        self.job_type = [complicated calculation that depends on inst values]
        self.invoice_status = [complicated calculation that depends on inst values]


    def get_booking_color(self, inst):
        if self.invoice_status == 1:
            if self.job_type == 1:
                return "#000000"
            elif self.job_type == 2:
                return "#f1c40f"
            elif self.job_type == 3:
                return "#FFFFF"
        else:
            return '#faase4'


    def get_text_color(self, inst):
        if self.invoice_status == 2:
            if self.job_type == 1:
                return "#BBFF33"
            elif self.job_type == 2:
                return "#272844"
            elif self.job_type == 3:
                return "#2c0716"
        else:
            return '#FFFFF'

1 Ответ

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

Полагаю, вам нужно изменить свой __init__() вызов на это:

     def __init__(self, instance=None, data=empty, **kwargs):
         self.job_type = [complicated calculation that depends on inst values]
         self.invoice_status = [complicated calculation that depends on inst values]
         super(CalendarViewSerializer, self).__init__(**kwargs)

Я бы также рекомендовал переименовать ваш класс в CalendarViewSerializer, чтобы его не перепутали с кем-либо еще.

Вы также можете перемещаться, переопределяя вызов __init__(), передавая эти вычисления через контекст - затем работая с ними оттуда ... например,

serializer = CalendarViewSerializer(data=request.data, context={'job_type': ..., 'invoice_status': ...})
class CalendarViewSerializer(serializers.ModelSerializer):

    booking_color = serializers.SerializerMethodField()
    text_color = serializers.SerializerMethodField()

    def get_booking_color(self, inst):
        if self.context['invoice_status'] == 1:
            if self.context['job_type'] == 1:
                return "#000"
            elif self.context['job_type'] == 2:
                return "#f1c40f"
            elif self.context['job_type'] == 3:
                return "#fff"
            else:
                return '#faase4'

    def get_text_color(self, inst):
        if self.context['invoice_status'] == 2:
            if self.context['job_type'] == 1:
                return "#bbff33"
            elif self.context['job_type'] == 2:
                return "#272844"
            elif self.context['job_type'] == 3:
                return "#2c0716"
            else:
                return '#fff'

Как дополнительный бонус, я полагаю, вы могли бы использовать какой-то объект dict() / {} для возврата шестнадцатеричных кодов из поиска ключей, а не операторы if elseif elseif else.

...