Как получить user_id из JWT токена ? Django Rest Framework

Мне нужно из jwt токена получить user_id, чтобы подставить его в соответствующее поле при создании поста. Однажды я это уже делал в своем другом проекте, но теперь так не работает

Раньше я в сериализаторе для модели переопределял метод create и из аргумента request получал нужное значение, но в последней версии drf отсутствует request в методе create, теперь там validated_data и как из него получить через токен user_id я не понимаю

Сейчас метод create выглядит вот так:

def create(self, validated_data):

Раньше это работало вот так:

class UserAnswersSerializer(serializers.ModelSerializer):
    user = serializers.StringRelatedField(many=False)

    class Meta:
        model = UserAnswer
        fields = ('__all__')

    def create(self, request):
        data = request.data
        print(data)
        print(request.user)
        question = Question.objects.get(id=data['questionId'])
        user = User.objects.get(username=request.user)
        testId = Test.objects.get(id=data['testId'])
        answers = data['answers']
        user_answer = UserAnswer()
        user_answer.user = user
        user_answer.question = question
        user_answer.testId = testId
        user_answer.answers = answers
        answers_for_question = question.answers.all()
        right_answer = []
        list_answers = answers.split(',')
        for j in answers_for_question:
            if j.right:
                right_answer.append(j.text)
        print(right_answer)
        print(list_answers)
        print(right_answer == list_answers)
        if right_answer == list_answers:
            right = True
        else:
            right = False
        user_answer.right = right
        user_answer.save()
        return user_answer 

Нашел способ, нужно переопределить метод perfom_create в нужной вьюхе и там передать user в нужный сериализатор, например вот так :

class PostViewSet(LikedMixin, viewsets.ModelViewSet):
    queryset = Post.objects.all()
    serializer_class = PostSerializer
    permission_classes = (IsAuthenticatedOrReadOnly,)

    def perform_create(self, serializer):
        user = self.request.user
        print(user)
        serializer.save(user=user)

Вы можете сделать Middleware, который по jwt токену определит пользователя. И засунет его в request. И в вашем viewset будет пользователь.

Пример (реализация из проекта, возможно вам придется адаптировать под свои нужны):

from dj_rest_auth.jwt_auth import JWTCookieAuthentication
from django.contrib.auth.middleware import get_user
from django.utils.functional import SimpleLazyObject
from django.utils.deprecation import MiddlewareMixin

class JWTAuthenticationMiddleware(object):
   """
   При аутентификации с помощью JWT cookie поле user в запросе
   не заполняется заполняем его при помощи данного middleware
   """
   def __init__(self, get_response):
       self.get_response = get_response

   def __call__(self, request):
       request.user = SimpleLazyObject(lambda: 
                             self.__class__.get_jwt_user(request))
    return self.get_response(request)

@staticmethod
def get_jwt_user(request):
    user = get_user(request)
    if user.is_authenticated:
        return user
    jwt_authentication = JWTCookieAuthentication()
    result = jwt_authentication.authenticate(request)
    if result:
        user = result[0]
    return user
Вернуться на верх