#python #django #django-rest-framework
Вопрос:
Я тестирую API приложения Django (DRF).
Я звоню http://127.0.0.1:8000/api/users/1/documents/ (1 — идентификатор пользователя) И получите сообщение об ошибке
...
File "/app/backend/apps/users/views/users/views.py" in create
542. serializer = self.get_serializer(data=request.data)
File "/usr/local/lib/python3.7/site-packages/rest_framework/generics.py" in get_serializer
110. return serializer_class(*args, **kwargs)
Exception Type: TypeError at /api/users/1/documents/
Exception Value: 'NoneType' object is not callable
Как я могу определить проблему?
Представление, связанное с запросом /app/backend/apps/users/views/users/views.py (проблемная строка есть serializer = self.get_serializer(data=request.data)
)
class UserDocumentCreate(generics.CreateAPIView, generics.RetrieveAPIView):
serializer_class = UserDocumentSerializer
permission_classes = (UserIsOwner, IsAuthenticatedDriver)
queryset = Document.objects.all()
def get_serializer_class(self):
if self.request.version == "1.0":
return UserDocumentSerializer
# return UserDocumentSerializer2
def create(self, request, *args, **kwargs):
request.data._mutable = True
request.data["owner"] = kwargs.get("pk")
serializer = self.get_serializer(data=request.data)
if serializer.is_valid(raise_exception=True):
owner = serializer.validated_data.get("owner")
document_type = serializer.validated_data.get("document_type")
message_status = request.data.get("message_status")
documents = owner.document_owner.filter(
document_type=document_type
)
for document in documents:
if document.status == DocumentStatus.DOCUMENT_REJECTED_STATUS:
document.delete()
# Mark user as new
owner.is_new_user = True
owner.save()
self.perform_create(serializer)
headers = self.get_success_headers(serializer.data)
response = {
"status": status.HTTP_201_CREATED,
"result": serializer.data,
}
# accept corresponding registration message
if message_status:
driver_reg = DriverRegistration.objects.filter(user=kwargs.get("pk")).first()
driver_reg.accept_by_status(message_status)
next_id = driver_reg.get_next()
# add information about next registration message to response
if next_id != -1:
response["next_message"] = REG_MESSAGES[next_id].to_json()
return Response(
response, status=status.HTTP_201_CREATED, headers=headers
)
Связанный сериализатор (ничего особенного)
class UserDocumentSerializer(serializers.ModelSerializer):
is_new_document = serializers.BooleanField(read_only=True)
class Meta:
model = Document
fields = (
"id",
"owner",
"file",
"document_type",
"uploaded_at",
"is_new_document",
)
Комментарии:
1. Вы пишете
if self.request.version == "1.0":
и возвращаете сериализатор для этого, но что произойдет, если это условие ложно?
Ответ №1:
Вам нужно всегда возвращать значение из get_serializer_class
метода.
Вам нужно реализовать условие else либо явно (например, в качестве одиночки, которое вы прокомментировали), либо с помощью метода serializer_class
, либо возвращаясь к суперметоду.
class UserDocumentCreate(generics.CreateAPIView, generics.RetrieveAPIView):
serializer_class = UserDocumentSerializer
permission_classes = (UserIsOwner, IsAuthenticatedDriver)
queryset = Document.objects.all()
def get_serializer_class(self):
if self.request.version == "1.0":
return UserDocumentSerializer
else:
# explicit
return UserDocumentSerializer2
# property
return self.serializer_class
# super
return super(UserDocumentCreate, self).get_serializer_class()