我正在尝试创建一个 APIView(urls.py 中的路径“create-room”),如果会话已存在,我可以在其中编辑 Room 模型,如果会话不存在,我可以创建一个新的 Room 模型。在 APIView 中,。 我不知道为什么它说
GET /api/create-room
,这导致了HTTP 405 Method Not Allowed
的错误。
如何将请求更改为 POST 请求,如 (写作 POST /api/create-room
而不是 GET
)
这是我的代码:
# views.py
from django.shortcuts import render
from rest_framework import generics, status
from .serializers import RoomSerializer, CreateRoomSerializer
from .models import Room
from rest_framework.views import APIView
from rest_framework.response import Response
# Create your views here.
class RoomView(generics.ListAPIView):
queryset = Room.objects.all()
serializer_class = RoomSerializer
# The problematic API View
class CreateRoomView(APIView):
serializer_class = CreateRoomSerializer
def post(self, request, format=None):
if not self.request.session.exists(self.request.session.session_key):
self.request.session.create()
serializer = self.serializer_class(data=request.data)
if serializer.is_valid():
guest_can_pause = serializer.data.get('guest_can_pause')
votes_to_skip = serializer.data.get('votes_to_skip')
host = self.request.session.session_key
# Check if host already has a session
queryset = Room.objects.filter(host=host)
if queryset.exists():
room = queryset[0]
room.guest_can_pause = guest_can_pause
room.votes_to_skip = votes_to_skip
room.save(update_fields=['guest_can_pause', 'votes_to_skip'])
return Response(RoomSerializer(room).data, status=status.HTTP_200_OK)
else:
room = Room(host=host, guest_can_pause=guest_can_pause,
votes_to_skip=votes_to_skip)
room.save()
return Response(RoomSerializer(room).data, status=status.HTTP_201_CREATED)
return Response({'Bad Request': 'Invalid data...'}, status=status.HTTP_400_BAD_REQUEST)
# serializers.py
from rest_framework import serializers
from .models import Room
class RoomSerializer(serializers.ModelSerializer):
class Meta:
model = Room
fields = ('id', 'code', 'host', 'guest_can_pause',
'votes_to_skip', 'created_at')
class CreateRoomSerializer(serializers.ModelSerializer):
class Meta:
model = Room
fields = ('guest_can_pause', 'votes_to_skip')
# urls.py
from django.urls import path
from . import views
# URLConf
urlpatterns = [
path('room', views.RoomView.as_view()),
path('create-room', views.CreateRoomView.as_view())
]
我尝试将这段代码添加到我的视图中
def get(self, request, format=None):
queryset = Room.objects.all()
serializer = self.serializer_class()
return Response(serializer.data)
希望这个答案对你有用
# views.py
from django.shortcuts import render
from rest_framework import generics, status
from rest_framework.exceptions import ValidationError
from .serializers import RoomSerializer, CreateRoomSerializer
from .models import Room
from rest_framework.views import APIView
from rest_framework.response import Response
# class RoomView(generics.ListAPIView):
# queryset = Room.objects.all()
# #serializer_class = RoomSerializer
# serializers = CreateRoomSerializer
# The problematic API View
class RoomAPIView(APIView):
serializer_class = RoomSerializer
def get(self, request, format=None):
queryset = Room.objects.all()
data = RoomSerializer(data=queryset, many=True)
return Response(data=data)
def post(self, request, format=None):
if not self.request.session.exists(self.request.session.session_key):
self.request.session.create()
serializer = CreateRoomSerializer(data=request.data)
try:
serializer.is_valid(raise_exception=True)
except ValidationError:
return Response({'Bad Request': 'Invalid data...'}, status=status.HTTP_400_BAD_REQUEST)
# Check if host already has a session
host = self.request.session.session_key
room, is_created = Room.objects.update_or_create(
host=host,
defaults={
"guest_can_pause": serializer.data['guest_can_pause'],
"votes_to_skip": serializer.data['votes_to_skip'],
},
)
return Response(
data=RoomSerializer(room).data,
status=status.HTTP_201_CREATED,
)
# serializer = self.serializer_class(data=request.data)
# if serializer.is_valid():
# guest_can_pause = serializer.data.get('guest_can_pause')
# votes_to_skip = serializer.data.get('votes_to_skip')
# host = self.request.session.session_key
# # Check if host already has a session
# queryset = Room.objects.filter(host=host)
# if queryset.exists():
# room = queryset[0]
# room.guest_can_pause = guest_can_pause
# room.votes_to_skip = votes_to_skip
# room.save(update_fields=['guest_can_pause', 'votes_to_skip'])
# return Response(RoomSerializer(room).data, status=status.HTTP_200_OK)
# else:
# room = Room(host=host, guest_can_pause=guest_can_pause,
# votes_to_skip=votes_to_skip)
# room.save()
# return Response(RoomSerializer(room).data, status=status.HTTP_201_CREATED)
#
# return Response({'Bad Request': 'Invalid data...'}, status=status.HTTP_400_BAD_REQUEST)
建议将APIView统一为一个
# urls.py
from django.urls import path
from . import views
# URLConf
urlpatterns = [
path('api/rooms/', views.RoomAPIView.as_view()),
]