Как сопоставить различные типы запросов с различными представлениями, используя один и тот же точный путь в Django REST Framework?

Я хочу иметь url типа api/instrument/{id} и затем на основе типа запроса GET, POST, DELETE направить запрос к другому представлению в моем приложении Django.

У меня такие взгляды:

from django.shortcuts import render
from django.http.response import JsonResponse, 
from django.http.request import HttpRequest
from rest_framework.parsers import JSONParser
from rest_framework import status
from Instruments.services import instruments_service
from models import Instrument
from serializers import InstrumentsSerializer
from rest_framework.decorators import api_view
from services import InstrumentsService

# Application views live here
@api_view('GET')
def get_instrument_by_id(request:HttpRequest, id):
    instrument_service = InstrumentsService()
 
    data={}
    try:    
        data = instrument_service.get_instrument_by_id(id)
        return JsonResponse(data,status=status.HTTP_200_OK, safe=False)
    except Exception as exc:
        return JsonResponse({"Status":f"Error: {exc}"},status=status.HTTP_404_NOT_FOUND , safe=False)


@api_view('POST')
def update_instrument_by_id(request:HttpRequest, id):
    instrument_service = InstrumentsService()
    instrument_data = JSONParser().parse(request)
    
 
    data={}
    try:    
        data = instrument_service.update_instrument_by_id(id, instrument_data)
        return JsonResponse(data,status=status.HTTP_200_OK, safe=False)
    except Exception as exc:
        return JsonResponse({"Status":f"Error: {exc}"},status=status.HTTP_404_NOT_FOUND , safe=False)


@api_view('DELETE')
def delete_instrument_by_id(request:HttpRequest, id):
    instrument_service = InstrumentsService()
 
    data={}
    try:    
        data = instrument_service.delete_instrument_by_id(id)
        return JsonResponse(data,status=status.HTTP_200_OK, safe=False)
    except Exception as exc:
        return JsonResponse({"Status":f"Error: {exc}"},status=status.HTTP_404_NOT_FOUND , safe=False)

Я вижу, что люди, использующие django, делают ОДНУ функцию для обработки всех запросов, а затем внутри нее располагают logioc, но мне это кажется неправильным. Есть ли способ сопоставить одну и ту же конечную точку URL с разными функциями в зависимости от типа запроса?

Я вижу здесь, например, что каждый url отображается на представление, но тип запроса нигде не указан URL_Dispatcher

Ок, основываясь на представлениях на основе классов, которые предлагает Django REST framework и которые были предложены в комментариях к исходному посту, я сделал этот класс, который автоматически обрабатывает все типы запросов на основе их типа в одной конечной точке:

from uuid import UUID
from django.shortcuts import render
from django.http.response import JsonResponse
from django.http.request import HttpRequest
from rest_framework import viewsets, status
from rest_framework.parsers import JSONParser
from rest_framework.response import Response
from Instruments.services import InstrumentsService
from rest_framework.decorators import api_view
from Instruments.services import InstrumentsService
from injector import singleton, inject


# Application views live here
@singleton
class InstrumentViewSet(viewsets.ModelViewSet):
    @inject
    def __init__(self, instrument_service: InstrumentsService, **kwargs):
        self.instrument_service = instrument_service
        super().__init__(**kwargs)

    def list(self, request: HttpRequest):
        data = {}

        try:
            data = self.instrument_service.get_instruments()
            return JsonResponse(data, status=status.HTTP_200_OK, safe=False)
        except Exception as exc:
            return JsonResponse(
                {"Status": f"Error: {exc}"},
                status=status.HTTP_400_BAD_REQUEST,
                safe=False,
            )

    def create(self, request):
        instrument_data = JSONParser().parse(request)
        data = {}

        try:
            data = self.instrument_service.add_instrument(instrument_data)
            return JsonResponse(data, status=status.HTTP_201_CREATED, safe=False)
        except Exception as exc:
            return JsonResponse(data, status=status.HTTP_400_BAD_REQUEST, safe=False)

    def retrieve(self, request, pk: UUID = None):
        data = {}

        try:
            data = self.instrument_service.get_instrument_by_id(pk)
            return JsonResponse(data, status=status.HTTP_200_OK, safe=False)
        except Exception as exc:
            return JsonResponse(
                {"Status": f"Error: {exc}"},
                status=status.HTTP_404_NOT_FOUND,
                safe=False,
            )

    def update(self, request, pk: UUID = None):
        instrument_data = JSONParser().parse(request)
        data = {}

        try:
            data = self.instrument_service.update_instrument_by_id(pk, instrument_data)
            return JsonResponse(data, status=status.HTTP_200_OK, safe=False)
        except Exception as exc:
            return JsonResponse(
                {"Status": f"Error: {exc}"},
                status=status.HTTP_404_NOT_FOUND,
                safe=False,
            )

    def destroy(self, request, pk: UUID = None):
        data = {}
        try:
            data = self.instrument_service.delete_instrument_by_id(pk)
            return JsonResponse(data, status=status.HTTP_200_OK, safe=False)
        except Exception as exc:
            return JsonResponse(
                {"Status": f"Error: {exc}"},
                status=status.HTTP_404_NOT_FOUND,
                safe=False,
            )
Вернуться на верх