Django / Django Rest Framework ModelViewSet: __init__() принимает 1 позиционный аргумент, но было задано 2
Я пытаюсь создать пользовательский "список" в OptionViewSet, но он выдает ошибку.
class OptionViewSet(viewsets.ModelViewSet):
serializer_class = OptionSerializer
queryset = Option.objects.all()
def list(self, request):
queryset = Option.objects.all()
serializer = OptionSerializer(queryset, many=True)
return Response(serializer.data)
Ошибка
__init__() takes 1 positional argument but 2 were given
Это работает нормально:
class OptionViewSet(viewsets.ModelViewSet):
serializer_class = OptionSerializer
queryset = Option.objects.all()
urls.py
path('api/shipping/', include((shipping_routes.urls, 'shipping'), namespace='shipping')),
routes.py
routes.register(r'option', OptionViewSet, basename='option')
serializer
class OptionSerializer(serializers.ModelSerializer):
class Meta:
model = Option
fields = ['id', 'extra', 'name']
полное отслеживание
Traceback (most recent call last):
File "C:\Users\Simon\.virtualenvs\django_backend-ZmgaAA1F\lib\site-packages\django\core\handlers\exception.py", line 47, in inner
response = get_response(request)
File "C:\Users\Simon\.virtualenvs\django_backend-ZmgaAA1F\lib\site-packages\django\core\handlers\base.py", line 181, in _get_response
response = wrapped_callback(request, *callback_args, **callback_kwargs)
File "C:\Users\Simon\.virtualenvs\django_backend-ZmgaAA1F\lib\site-packages\django\views\decorators\csrf.py", line 54, in wrapped_view
return view_func(*args, **kwargs)
File "C:\Users\Simon\.virtualenvs\django_backend-ZmgaAA1F\lib\site-packages\rest_framework\viewsets.py", line 125, in view
return self.dispatch(request, *args, **kwargs)
File "C:\Users\Simon\.virtualenvs\django_backend-ZmgaAA1F\lib\site-packages\rest_framework\views.py", line 509, in dispatch
response = self.handle_exception(exc)
File "C:\Users\Simon\.virtualenvs\django_backend-ZmgaAA1F\lib\site-packages\rest_framework\views.py", line 469, in handle_exception
self.raise_uncaught_exception(exc)
File "C:\Users\Simon\.virtualenvs\django_backend-ZmgaAA1F\lib\site-packages\rest_framework\views.py", line 480, in raise_uncaught_exception
raise exc
File "C:\Users\Simon\.virtualenvs\django_backend-ZmgaAA1F\lib\site-packages\rest_framework\views.py", line 506, in dispatch
response = handler(request, *args, **kwargs)
File "C:\Users\Simon\Documents\GitHub\crud-react-django\django_backend\shipping\views.py", line 18, in list
return Response(serializer.data)
Exception Type: TypeError at /api/shipping/option/
Exception Value: __init__() takes 1 positional argument but 2 were given
В url.py, в конкретном пути из urlpatters[] вам нужно вызвать ваш views.OptionViewSet.as_view()
как средний параметр между URL путем и ссылкой на имя:
path('api/shipping/', include((shipping_routes.urls, 'shipping'), namespace='shipping')),
Django имеет очень хорошую документацию, и вы можете прочитать больше о ViewSets в Django-Rest-Framework здесь: https://www.django-rest-framework.org/api-guide/viewsets/
По умолчанию viewsets.ModelViewSet
предоставляет полный набор действий create/list/retrieve/update/destroy
, если вам нужен пользовательский список, то я считаю, что вам следует рассмотреть базовые классы Custom ViewSet для настройки поведения.
Пример:
from rest_framework import mixins
class CreateListRetrieveViewSet(mixins.CreateModelMixin,
mixins.ListModelMixin,
mixins.RetrieveModelMixin,
viewsets.GenericViewSet):
"""
A viewset that provides `retrieve`, `create`, and `list` actions.
To use it, override the class and set the `.queryset` and
`.serializer_class` attributes.
"""
pass
Итак, если мы изменим ваш код в соответствии с этим подходом, то он должен выглядеть следующим образом;
class OptionViewSet(mixins.ListModelMixin, viewsets.GenericViewSet):
serializer_class = OptionSerializer
queryset = Option.objects.all()
def list(self, request):
queryset = Option.objects.all()
serializer = OptionSerializer(queryset, many=True)
return Response(serializer.data)
Если вы хотите расширить ModelViewSet
, то вы можете следовать документации, относящейся к Маркировка дополнительных действий для маршрутизации. Согласно этому подходу OptionViewSet
должен выглядеть следующим образом:
class OptionViewSet(viewsets.ModelViewSet):
serializer_class = OptionSerializer
queryset = Option.objects.all()
# ...
@action(detail=False, methods=['get'])
def custom_list(self, request):
queryset = Option.objects.all()
serializer = OptionSerializer(queryset, many=True)
return Response(serializer.data)
Я неправильно импортировал Response. Импортировал его из "requests" вместо "rest_framework.response".