#python #django
#python #django
Вопрос:
Я пытался решить эту проблему с циклическим импортом, чтобы реализовать модульное тестирование без сбоев. Если я могу показать вам короткую версию предыдущего решения, которое я получил:
Это….
serializer_class = serializers.CompanyMappingSerializer
должно быть изменено на это:
serializer_class = "serializers.CompanyMappingSerializer"
После этого модульные тесты выполняются нормально. Однако, когда я запускаю api с POSTMAN, он показывает эту ошибку:
TypeError at /api/v1/company/
'str' object is not callable
Что мне делать в этой ситуации?
PS: для получения дополнительной информации здесь приведена полная трассировка:
Traceback:
File "/Users/nick/myvenv/lib/python3.8/site-packages/django/core/handlers/exception.py" in inner
34. response = get_response(request)
File "/Users/nick/myvenv/lib/python3.8/site-packages/django/core/handlers/base.py" in _get_response
115. response = self.process_exception_by_middleware(e, request)
File "/Users/nick/myvenv/lib/python3.8/site-packages/django/core/handlers/base.py" in _get_response
113. response = wrapped_callback(request, *callback_args, **callback_kwargs)
File "/Users/nick/myvenv/lib/python3.8/site-packages/django/views/decorators/csrf.py" in wrapped_view
54. return view_func(*args, **kwargs)
File "/Users/nick/myvenv/lib/python3.8/site-packages/rest_framework/viewsets.py" in view
114. return self.dispatch(request, *args, **kwargs)
File "/Users/nick/myvenv/lib/python3.8/site-packages/rest_framework/views.py" in dispatch
505. response = self.handle_exception(exc)
File "/Users/nick/myvenv/lib/python3.8/site-packages/rest_framework/views.py" in handle_exception
465. self.raise_uncaught_exception(exc)
File "/Users/nick/myvenv/lib/python3.8/site-packages/rest_framework/views.py" in raise_uncaught_exception
476. raise exc
File "/Users/nick/myvenv/lib/python3.8/site-packages/rest_framework/views.py" in dispatch
502. response = handler(request, *args, **kwargs)
File "/Users/nick/work/shiftwork_backend/api/views/company.py" in list
74. serializer = self.get_serializer(page, many=True)
File "/Users/nick/myvenv/lib/python3.8/site-packages/rest_framework/generics.py" in get_serializer
110. return serializer_class(*args, **kwargs)
Exception Type: TypeError at /api/v1/company/
Exception Value: 'str' object is not callable
и ниже приведена более подробная версия api/company.py
...
...
from api.models import Company, Pattern, UserCompany, CompanyMapping, Category, COUNTRY_CODE_CHOICES
from statistics.models import CompanySearch
# from api.serializers import CompanySerializer, PatternSerializer, UserCompanySerializer, CompanyMappingSerializer, CategorySerializer
from api import serializers
from api.views import get_user_company_by_local_id, get_user_pattern_by_local_id
...
...
class CompanyMappingViewSet(viewsets.ModelViewSet):
queryset = CompanyMapping.objects.all()
serializer_class = serializers.CompanyMappingSerializer
permission_classes = (IsAuthenticated,)
Комментарии:
1. Это означает, что serializer_class — это строка, и я предполагаю, что вы делаете что-то вроде
serializer_class()
, пожалуйста, включите немного больше кода и полную обратную трассировку ошибок.2. изменение типа на строку действительно допустимо только для аннотаций типов, а не для фактических типов как переменных первого класса — вам, по всей вероятности, придется прервать фактический цикл
Ответ №1:
Ошибка заключается в том, что вы определили serializer_class
атрибут как строку, а не как класс. Таким образом, это должно быть как
class CompanyMappingViewSet(viewsets.ModelViewSet):
queryset = CompanyMapping.objects.all()
serializer_class = serializers.CompanyMappingSerializer
permission_classes = (IsAuthenticated,)
Если вы хотите исключить проблему с циклическим импортом, вы можете использовать get_serializer_class(...)
метод как,
class CompanyMappingViewSet(viewsets.ModelViewSet):
queryset = CompanyMapping.objects.all()
serializer_class = serializers.CompanyMappingSerializer
permission_classes = (IsAuthenticated,)
def get_serializer_class(self):
from api.serializers import CompanyMappingSerializer
return CompanyMappingSerializer
Ответ №2:
Я не знаю, лучшее ли это решение, но если вы не можете что-то сделать, чтобы разорвать циклический цикл, вы можете переопределить свой сериализатор get_serializer_class
и добавить свой импорт в этот метод, например:
class CompanyMappingViewSet(viewsets.ModelViewSet):
queryset = CompanyMapping.objects.all()
permission_classes = (IsAuthenticated,)
def get_serializer_class(self):
from api.serializer import CompanyMappingSerializer
return CompanyMappingSerializer
И это должно предотвратить циклический импорт.