Из библиотеки django можем ли мы перезаписать только части viewset вместо полной перезаписи viewset?

#python #django #django-rest-framework #django-rest-viewsets #djoser

#python #django #django-rest-framework #django-rest-viewsets #джосер

Вопрос:

Я работаю с djoser и, прочитав документацию, хочу изменить некоторые части кода из Userviewset.
Я хочу перезаписать def me(self, request, *args, **kwargs) и настроить его. Для запроса get вместо возврата всех полей модели я хочу вернуть только имя пользователя и фотографию профиля.
Я пытался сделать from djoser.views import UserViewSet . Тогда,

 class UserViewSet(viewsets.ModelViewSet):

    # from djoser docs which I want to update
    @action(["get", "put", "patch", "delete"], detail=False)
    def me(self, request, *args, **kwargs):
        self.get_object = self.get_instance
        if request.method == "GET":
            return self.retrieve(request, *args, **kwargs)
        elif request.method == "PUT":
            return self.update(request, *args, **kwargs)
        elif request.method == "PATCH":
            return self.partial_update(request, *args, **kwargs)
        elif request.method == "DELETE":
            return self.destroy(request, *args, **kwargs)
  

Но мне интересно, что это сработает, поскольку ни retrieve ни get_instance не упоминаются.
Есть ли более короткий правильный способ сделать это?

Ответ №1:

Если вы хотите вернуть другой ответ для GET /users/me , вам нужно только изменить свой сериализатор.

Вы можете сделать это даже без создания подклассов UserViewSet . В UserViewSet.get_serializer_class есть

       elif self.action == "me":
            return settings.SERIALIZERS.current_user
  

поэтому назначьте другой сериализатор в настройках djoser.

Смотрите документы

Ответ №2:

Не трогайте viewset, если вы хотите, чтобы более поздние данные, которые вы хотите вернуть, переопределили, пожалуйста, сериализатор, который использует djoser. Это пример сериализатора

 from djoser.serializers import UserSerializer
class CustomUserSerializer(UserSerializer):
    avatar = serializers.SerializerMethodField()
    
    def get_avatar(self, obj):
        return obj.profile.avatar.url if obj.profile.avatar else ""

    class Meta:
        model = User
        fields = ("username", "first_name", "avatar")
  

Затем используйте этот сериализатор в настройках DJOSER

 DJOSER = {
    "..."
    "SERIALIZERS":{
        'current_user': 'bingo.serializers.CustomUserSerializer',
    }
}