Django rest framework 可以使用DRF中的super()更改方法中间的代码字符串
我想对以下序列化程序进行子类化:Django rest framework 可以使用DRF中的super()更改方法中间的代码字符串,django-rest-framework,Django Rest Framework,我想对以下序列化程序进行子类化: User = get_user_model() class UidAndTokenSerializer(serializers.Serializer): uid = serializers.CharField() token = serializers.CharField() default_error_messages = { "invalid_token": settings.CONSTANTS.message
User = get_user_model()
class UidAndTokenSerializer(serializers.Serializer):
uid = serializers.CharField()
token = serializers.CharField()
default_error_messages = {
"invalid_token": settings.CONSTANTS.messages.INVALID_TOKEN_ERROR,
"invalid_uid": settings.CONSTANTS.messages.INVALID_UID_ERROR,
}
def validate(self, attrs):
validated_data = super().validate(attrs)
# uid validation have to be here, because validate_<field_name>
# doesn't work with modelserializer
try:
uid = utils.decode_uid(self.initial_data.get("uid", ""))
self.user = User.objects.get(pk=uid)
except (User.DoesNotExist, ValueError, TypeError, OverflowError):
key_error = "invalid_uid"
raise ValidationError(
{"uid": [self.error_messages[key_error]]}, code=key_error
)
is_token_valid = self.context["view"].token_generator.check_token(
self.user, self.initial_data.get("token", "")
)
if is_token_valid:
return validated_data
else:
key_error = "invalid_token"
raise ValidationError(
{"token": [self.error_messages[key_error]]}, code=key_error
)
到
有没有办法用super()
来实现这一点,而不是将整个内容从超类复制粘贴到子类?
非常感谢。
我现在做的,有点粗略
class CommitUndeleteUserAccountSerializer(UidAndTokenSerializer):
def validate(self, attrs):
User = get_user_model()
User.objects = User._default_manager
attrs = super().validate(attrs)
if not self.user.deleted:
raise serializers.ValidationError(
*error_codes.NOT_SOFT_DELETED
)
return attrs
它可以工作,但可能很危险。您可以定义特殊的方法来获取用户实例:
class UidAndTokenSerializer(serializers.Serializer):
uid = serializers.CharField()
token = serializers.CharField()
default_error_messages = {
"invalid_token": settings.CONSTANTS.messages.INVALID_TOKEN_ERROR,
"invalid_uid": settings.CONSTANTS.messages.INVALID_UID_ERROR,
}
def _get_user(self, uid):
return get_user_model().objects.get(pk=uid)
def validate(self, attrs):
validated_data = super().validate(attrs)
# uid validation have to be here, because validate_<field_name>
# doesn't work with modelserializer
try:
uid = utils.decode_uid(self.initial_data.get("uid", ""))
self.user = self._get_user(uid=uid)
except (User.DoesNotExist, ValueError, TypeError, OverflowError):
key_error = "invalid_uid"
raise ValidationError(
{"uid": [self.error_messages[key_error]]}, code=key_error
)
is_token_valid = self.context["view"].token_generator.check_token(
self.user, self.initial_data.get("token", "")
)
if is_token_valid:
return validated_data
else:
key_error = "invalid_token"
raise ValidationError(
{"token": [self.error_messages[key_error]]}, code=key_error
)
如果没有这些危险的与manager共舞的话,问题在于超类在第三部分包的源代码中。我不能修改it@AlekseiKhatkevich然后创建自己的基本序列化程序类,重写validate方法和add _get_user方法
class CommitUndeleteUserAccountSerializer(UidAndTokenSerializer):
def validate(self, attrs):
User = get_user_model()
User.objects = User._default_manager
attrs = super().validate(attrs)
if not self.user.deleted:
raise serializers.ValidationError(
*error_codes.NOT_SOFT_DELETED
)
return attrs
class UidAndTokenSerializer(serializers.Serializer):
uid = serializers.CharField()
token = serializers.CharField()
default_error_messages = {
"invalid_token": settings.CONSTANTS.messages.INVALID_TOKEN_ERROR,
"invalid_uid": settings.CONSTANTS.messages.INVALID_UID_ERROR,
}
def _get_user(self, uid):
return get_user_model().objects.get(pk=uid)
def validate(self, attrs):
validated_data = super().validate(attrs)
# uid validation have to be here, because validate_<field_name>
# doesn't work with modelserializer
try:
uid = utils.decode_uid(self.initial_data.get("uid", ""))
self.user = self._get_user(uid=uid)
except (User.DoesNotExist, ValueError, TypeError, OverflowError):
key_error = "invalid_uid"
raise ValidationError(
{"uid": [self.error_messages[key_error]]}, code=key_error
)
is_token_valid = self.context["view"].token_generator.check_token(
self.user, self.initial_data.get("token", "")
)
if is_token_valid:
return validated_data
else:
key_error = "invalid_token"
raise ValidationError(
{"token": [self.error_messages[key_error]]}, code=key_error
)
class CommitUndeleteUserAccountSerializer(UidAndTokenSerializer):
def _get_user(self, uid):
return get_user_model()._default_manager.get(pk=uid)
def validate(self, attrs):
attrs = super().validate(attrs)
if not self.user.deleted:
raise serializers.ValidationError(
*error_codes.NOT_SOFT_DELETED
)
return attrs