Несколько общих представлений под одним URL
У меня возникла проблема с установкой нескольких общих представлений на одном и том же определенном URL. Я бы хотел, чтобы мой API был смоделирован следующим образом:
GET /cars/ <- список автомобилей
POST /cars/ <- добавить новый автомобиль
GET /cars/uuid/ <- получить конкретный автомобиль
PUT /cars/uuid/ <- редактирование конкретного автомобиля
DELETE /cars/uuid/ <- удаление конкретного автомобиля
В итоге моя проблема заключается в том, что первый include в urlconfig способен выполнить HTTP метод, на остальные я всегда получаю "Method Not Allowed:". В приведенном выше примере это происходит для PUT и DELETE. Можно ли разрешить URL как указано выше или нужно добавить префиксы, например /cars/get/uuid?
urls.py
urlpatterns = [
path('', CarListApi.as_view(), name='list'),
path('', CarCreateApi.as_view(), name='create'),
path('<uuid:uuid>/', CarDeleteApi.as_view(), name='delete'),
path('<uuid:uuid>/', CarUpdateApi.as_view(), name='update'),
path('<uuid:uuid>/', CarDetailApi.as_view(), name='detail'),
]
partial views.py
class CarUpdateApi(generics.UpdateAPIView,
generics.GenericAPIView):
permission_classes = (IsOwnerOrReadOnly,)
lookup_field = 'uuid'
http_method_names = ['delete', 'get', 'post', 'put']
@extend_schema_serializer(component_name="CarUpdateInputSerializer")
class InputSerializer(serializers.ModelSerializer):
class Meta:
model = Car
fields = ['plate', 'make', 'model', 'uuid']
@extend_schema(request=InputSerializer, responses={201: InputSerializer})
def put(self, request, uuid):
serializer = self.InputSerializer(data=request.data, context={'request': request})
if serializer.is_valid(raise_exception=True):
car = car_update(serializer.validated_data, uuid)
return Response(self.InputSerializer(car).data, status=status.HTTP_201_CREATED)
return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)
class CarDeleteApi(generics.DestroyAPIView,
generics.GenericAPIView):
http_method_names = ['delete', 'get', 'post', 'put']
@extend_schema_serializer(component_name='CarDeleteInputSerializer')
class InputSerializer(serializers.ModelSerializer):
class Meta:
model = Car
fields = ['uuid']
def get_serializer_class(self):
return self.InputSerializer
def delete(self, request, uuid, *args, **kwargs):
serializer = self.InputSerializer(data=request.data)
if serializer.is_valid(raise_exception=True) and car_delete(uuid):
return Response(status=status.HTTP_200_OK)
return Response(serializer.errors, status=status.HTTP_404_NOT_FOUND)
Есть идеи, как исправить эту проблему?
В шаблоне url должны быть только урлы, а в представлениях вы отделили бизнес-логику для http-методов. На urls.py:
urlpatterns = [
path('', CarApi.as_view(), name='car'),
path('<uuid:uuid>/', SpecificApi.as_view(), name='specific'),
]
и затем в представлениях, что-то вроде:
class CarApi(APIView):
def get(self, request):
# logic for get and return car list
def post(self, request):
# logic for add card