Сериализатор DjangoRestFramework не распознает атрибут "имя пользователя", даже если он существует
Это мой serializers.py:
from rest_framework import serializers
from django.contrib.auth.models import User
from CMSApp.mixins import SetCustomErrorMessagesMixin
from django.utils.translation import gettext as _
from rest_framework.validators import UniqueValidator
from django.core.validators import RegexValidator
class UserSerializer(SetCustomErrorMessagesMixin, serializers.ModelSerializer):
class Meta:
model = User
fields = ('username', 'password', 'email')
custom_error_messages_for_validators = {
'username': {
UniqueValidator: _('This username is already taken. Please, try again'),
RegexValidator: _('Invalid username')
}
}
def create(self, validated_data):
user = User.objects.create_user(
email = validated_data['email'],
username = validated_data['username'],
password = validated_data['password'],
)
return user
и это мой mixins.py:
class SetCustomErrorMessagesMixin:
"""
Replaces built-in validator messages with messages, defined in Meta class.
This mixin should be inherited before the actual Serializer class in order to call __init__ method.
Example of Meta class:
>>> class Meta:
>>> model = User
>>> fields = ('url', 'username', 'email', 'groups')
>>> custom_error_messages_for_validators = {
>>> 'username': {
>>> UniqueValidator: _('This username is already taken. Please, try again'),
>>> RegexValidator: _('Invalid username')
>>> }
>>> }
"""
def __init__(self, *args, **kwargs):
# noinspection PyArgumentList
super(SetCustomErrorMessagesMixin, self).__init__(*args, **kwargs)
self.replace_validators_messages()
def replace_validators_messages(self):
for field_name, validators_lookup in self.custom_error_messages_for_validators.items():
# noinspection PyUnresolvedReferences
for validator in self.fields[field_name].validators:
if type(validator) in validators_lookup:
validator.message = validators_lookup[type(validator)]
@property
def custom_error_messages_for_validators(self):
meta = getattr(self, 'Meta', None)
return getattr(meta, 'custom_error_messages_for_validators', {})
Когда я иду на URL /users/1, это представление, которое называется:
class user_detail(APIView):
"""
Get, update or delete a specific user.
"""
def get_object(self, pk):
try:
return User.objects.get(pk=pk)
except User.DoesNotExist:
return Response(status=status.HTTP_404_NOT_FOUND)
def get(self, request, pk):
user = self.get_object(pk)
serializer = UserSerializer(user)
return Response(serializer.data)
def put(self, request, pk):
user = self.get_object(pk)
serializer = UserSerializer(user, data=request.DATA)
if serialzier.is_valid():
serializier.save()
return Response(serializer.data)
return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)
def delete(self, request, pk):
user = self.get_object(pk)
user.delete()
return Response(status=status.HTTP_204_NO_CONTENT)
Проблема в том, что когда я захожу на URL /users/1, Django возвращает ошибку атрибута, говоря:
AttributeError at /CMS/users/1
Got AttributeError when attempting to get a value for field `username` on serializer `UserSerializer`.
The serializer field might be named incorrectly and not match any attribute or key on the `Response` instance.
Original exception text was: 'Response' object has no attribute 'username'.
Я проверил свой UserSerializer и правильно указал, что
fields = ('username', 'password', 'email')
так что я не могу найти проблему. Любая идея, почему Django выдает ошибку, говоря, что "Поле сериализатора может быть названо неправильно и не соответствовать ни одному атрибуту или ключу на Response
экземпляр.", хотя" имя пользователя "назван правильно?
1 ответ
Вопрос в вашем get_object
метод, вы возвращаете ответ 404 вместо повышения Http404
исключение. Из-за этого Response
передается в ваш сериализатор, и, очевидно, Response
не имеет username
поле.
Последняя часть вашей трассировки стека сказала
Исходный текст исключения был: у объекта "Response" нет атрибута "username".
Который был сигналом: есть только одно место, куда вы возвращаете Response
вернуться к сериализатору.