ModelSerializer — self. экземпляр является кортежем, когда экземпляр не передается

#python #django-rest-framework

#python #django-rest-framework

Вопрос:

Я создал ModelSerializer, который проверяет, принадлежит ли имя пользователя, введенное в форму входа, любому существующему пользователю. Кортеж передается аргументу instance ключевого слова по умолчанию вместо None при создании экземпляра сериализатора.

Смотрите: https://github.com/encode/django-rest-framework/blob/580bf45ccfd5c423a938729907d813f4862dca38/rest_framework/serializers.py#L84

Это приводит к возникновению ошибки при UniqueValidator вызове реализации. Здесь в exclude_current_instance методе возникает ошибка, поскольку instance это не фактическое значение None :

Смотрите: https://github.com/encode/django-rest-framework/blob/580bf45ccfd5c423a938729907d813f4862dca38/rest_framework/validators.py#L54

Я установил последнюю версию DRF (v.3.12.4) и просмотрел документы на Github, где я заметил это несоответствие.

Я не фокусируюсь на том, почему возникает ошибка. Вместо этого я пытаюсь понять, почему instance передается кортеж вместо None.

 class TestLoginSerializerUsername(TestCase):
    '''Verify that an anonymous user receives an error message
    when an attempt is made to log in with a username that is 
    not assigned to any user.'''

    @classmethod
    def setUpTestData(cls):
        User.objects.create_user("Alpha_user")
        User.objects.create_user("Beta_user")
        data = {
            "username": "ItsMe",
            "password": "secretpass"
        }
        request = APIRequestFactory()factory.post(
            reverse("accounts:login"), data=data, format="json"
        )

        cls.serializer = LoginSerializer(data=data, context={'request': request})
        cls.validated_serializer = cls.serializer.is_valid()
        cls.username_error = cls.serializer.errors['username'][0]

    def test_login_with_invalid_username(self):
        self.assertFalse(self.validated_serializer)
        self.assertEqual(
            str(self.username_error),
            "Login Denied: Username not registered."
        )

 
 class LoginSerializer(serializers.ModelSerializer):

    def __init__(self, *args, **kwargs):
        super().__init__(args, **kwargs)
        self.validate_errors = {}

    username = serializers.SlugField(
        min_length=4, max_length=13, validators=[
            UniqueValidator(
                User.objects.all(),
                "Login Denied: Username not registered",
                "iexact"
            )
        ]
    )
    password = serializers.RegexField(
        r"[0-9A-Za-z-_] ", min_length=5, max_length=9
    )

    class Meta:
        model = User
        fields = ['username', ]

 
 x = LoginSerializer()
>>> vars(x)
{'_args': (), '_kwargs': {}, 'instance': (), 'partial': False, 
'_context': {}, '_creation_counter': 5, 'read_only': False, 'write_only': False, 
'required': True, 'default': <class 'rest_framework.fields.empty'>, 
'source': None, 'initial': None, 'label': None, 'help_text': None, 
'style': {}, 'allow_null': False, 'field_name': None, 'parent': None, 
'error_messages': {'required': 'This field is required.', 
'null': 'This field may not be null.', 
'invalid': 'Invalid data. Expected a dictionary, but got {datatype}.'}, 
'validate_errors': {}}
>>> x.instance
()