Как сопоставить различные типы запросов с различными представлениями, используя один и тот же точный путь в 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,
)