Django REST Serializer постоянно изменяется в init

Я столкнулся со странной проблемой с DRF: у меня есть несколько сериализаторов, для которых я хочу отображать определенные поля только при определенных условиях, таких как наличие url-параметров в запросе или наличие у пользователя определенных прав.

Чтобы отделить логику представления моего сериализатора от бизнес-логики, я решил добавить атрибут conditional_fields к классу сериализатора Meta: это dict, в котором ключи - строки, представляющие условия, например "SHOW_HIDDEN_FIELDS", а их значения - списки имен полей, которые нужно удалить, если ключ не присутствует в сериализаторе context. Затем я переопределяю метод get_serializer_context моего набора представлений, чтобы получить нужные значения внутри контекста.

Я создал метод remove_unsatisfied_condition_fields, который делает следующее:

def remove_unsatisfied_condition_fields(self):
        conditional_fields = self.Meta.conditional_fields

        for condition, fields in conditional_fields.items():
            if not self.context.get(condition, False):
                for field in fields:
                    self.fields.pop(field, None)

Сериализаторы, использующие его, выглядят следующим образом:

class ExerciseSerializer(serializers.ModelSerializer):
    class Meta:
        model = Exercise
        fields = [
            "id",
            "text",
            "solution",
            "correct_choices"
        ]

        conditional_fields = {
            "EXERCISE_SHOW_HIDDEN_FIELDS": ["solution", "correct_choices"],
        }

Здесь возникает проблема: если я вручную вызываю этот метод внутри моих сериализаторов, в их методе __init__, вот так:

def __init__(self, *args, **kwargs):
        super().__init__(*args, **kwargs)
        self.remove_unsatisfied_condition_fields()

все работает нормально.

Однако, если я сделаю их наследуемыми от класса, который делает это автоматически, например, так:

class ConditionalFieldsMixin:
    def __init__(self, *args, **kwargs):
         super().__init__(*args, **kwargs)
         self.remove_unsatisfied_condition_fields()

    def remove_unsatisfied_condition_fields(self):
        conditional_fields = self.Meta.conditional_fields

        for condition, fields in conditional_fields.items():
            if not self.context.get(condition, False):
                for field in fields:
                    self.fields.pop(field, None)

и заставить мои сериализаторы наследоваться от него, происходит следующее:

как только приходит запрос, который не удовлетворяет одному из условий сериализатора conditional_fields, поле, кажется, "навсегда" удаляется из сериализатора: все последующие запросы, которые включают его, даже если они приводят к появлению context с надлежащими условиями для отображения этого поля, отвечают без этого поля. Как будто сериализатор перестает иметь это поле навсегда - только переразвертывание моего приложения заставляет его вернуться.

Это очень странно, и я понятия не имею, почему это происходит, только если удаление выполняется внутри класса в цепочке наследования сериализатора, а не в самом сериализаторе.

Связано ли это с каким-то странным правилом наследования Pythonic, о котором я не знаю, или я что-то упустил в сериализаторах?

Вернуться на верх