Как получить доступ к объекту пользователя в сериализаторе токенов Django Djoser

У меня в настройках есть:

DJOSER = {
    'SERIALIZERS': {
        'token': 'api.api.MyTokenSerializer'
    }
}

А вот этот сериализатор, используемый для входа в систему:

class MyTokenSerializer(TokenSerializer):
    auth_token = serializers.CharField(source="key")
    registration_complete = serializers.BooleanField(source="user.registration_complete", read_only=True)
    app_mode = serializers.CharField(source="user.app_mode", read_only=True)

    class Meta:
        model = djoser_settings.TOKEN_MODEL
        fields = ("auth_token", "profile_complete", "app_mode")

и теперь мне нужно добавить еще одно поле, но это поле является полем метода, и ему нужно user объект.

В псевдокоде:

class MyTokenSerializer(TokenSerializer):
    ...
    new_field = my_method(user_object)

    ...

Но я не понимаю, как получить доступ к объекту пользователя в этом сериализаторе. Я вижу чтоuser объект используется как источник в двух полях (registration_complete а также app_mode), но я не знаю, как получить к нему доступ напрямую, чтобы передать его методу. Можно ли получить доступ кuser объект здесь?

1 ответ

Решение

Вам нужен SerializerMethodField:

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

Этот метод принимает в качестве параметра сериализуемый объект. В вашем случае этоdjoser_settings.TOKEN_MODEL(который по умолчаниюrest_framework.authtoken.models.Token).

Если вы посмотрите на реализацию этой модели, вы увидите, что есть внешний ключ, указывающий на пользователя. Вот почему вы можете делать такие вещи, какsource=user.registration_complete (source на самом деле удобный ярлык для сериализации полей в посторонних объектах).

Итак, вы можете сделать что-то вроде этого:

class MyTokenSerializer(TokenSerializer):
    new_field = serializers.SerializerMethodField()

    def get_new_field(self, obj):
        # "obj" is a Token object
        user = obj.user

        # Return the value you want
        return f'Hello {user.email}'
Другие вопросы по тегам