Объект типа User не является JSON сериализуемым ошибка при регистрации с помощью пользовательского сериализатора
Я пытаюсь использовать сигналы для проверки того, вошел ли пользователь в систему или нет. Поскольку я использую DRF, когда пользователь входит в систему, он получает JWT-токен, мне нужно переписать validate
, чтобы срабатывал user-logged-in, когда пользователь получает действительный токен при входе в систему. Однако я получаю сообщение об ошибке:
Object of type User is not JSON serializable
Вот перечень того, что я пробовал:
вот моя конечная точка API входа в систему:
path('api/token/', CustomTokenObtainPairView.as_view(), name='token_obtain_pair'),
Мой CustomObtainPairView:
class CustomTokenObtainPairView(TokenObtainPairView):
serializer_class = CustomTokenObtainPairSerializer
Мой сериализатор CustomTokenPair:
from rest_framework_simplejwt.serializers import TokenObtainPairSerializer;
from rest_framework_simplejwt.views import TokenObtainPairView;
...
class CustomTokenObtainPairSerializer(TokenObtainPairSerializer):
def validate(self, attrs):
credentials = {
self.username_field: attrs.get(self.username_field),
'password': attrs.get('password')
}
if all(credentials.values()):
user = authenticate(request=self.context['request'], **credentials)
if user:
if not user.is_active:
msg = 'User account is disabled.'
raise serializers.ValidationError(msg)
user_logged_in.send(sender=user.__class__, request=self.context['request'], user=user)
return {
# 'token': jwt_encode_handler(payload),
'user': user
}
else:
msg = 'Unable to log in with provided credentials.'
raise serializers.ValidationError(msg)
else:
msg = 'Must include "{username_field}" and "password".'
msg = msg.format(username_field=self.username_field)
raise serializers.ValidationError(msg)
@classmethod
def get_token(cls, user):
token = super().get_token(user)
token['username'] = user.username
token['first_name'] = user.first_name
token['last_name'] = user.last_name
token['country'] = user.profile.country
token['city'] = user.profile.city
token['bio'] = user.profile.bio
token['photo'] = json.dumps(str(user.profile.profile_pic))
return token
и мои модели:
class UserLoginActivity(models.Model):
SUCCESS = 'S'
FAILED = 'F'
LOGIN_STATUS = ((SUCCESS, 'Success'),
(FAILED, 'Failed'))
login_IP = models.GenericIPAddressField(null=True, blank=True)
login_datetime = models.DateTimeField(auto_now=True)
login_username = models.CharField(max_length=40, null=True, blank=True)
status = models.CharField(max_length=1,
default=SUCCESS,
choices=LOGIN_STATUS,
null=True,
blank=True)
user_agent_info = models.CharField(max_length=255)
class Meta:
verbose_name = 'user_login_activity'
verbose_name_plural = 'user_login_activities'
Я следовал этому руководству: https://medium.com/@atulmishra_69567/tracking-user-login-activity-in-django-rest-framework-jwt-authentication-32e0194e77d0
Любая помощь будет очень признательна
Согласно реализации TokenObtainPairSerializer
и TokenObtainPairView
, вы должны вернуть сериализуемый вывод JSON из метода validate(...)
.
IMO, простой метод - использовать UserSerializer для сериализации экземпляра user
.
from rest_framework import serializers
from django.contrib.auth import get_user_model
User = get_user_model()
class UserSerializer(serializers.ModelSerializer):
class Meta:
model = User
fields = "__all__"
class CustomTokenObtainPairSerializer(TokenObtainPairSerializer):
def validate(self, attrs):
...
user = obtain_user_somehow_after_auth()
"""
alternatively, you can use this too
return {"user":{"id":user.pk, "email":user.email}}
"""
return {"user": UserSerializer(user).data}