【问题标题】:POST returns "detail": "Method \"GET\" not allowed."POST 返回“详细信息”:“方法 \"GET\" 不允许。”
【发布时间】:2020-12-12 18:10:23
【问题描述】:

项目的运作方式是在创建房间时应该给出一个随机代码(避免重复和猜测没有被占用的代码),并且主人应该创建自己的名字。

在文件中,我创建了房间并生成了一个在创建房间时应该给出的随机代码,但我收到了 HTTP 405 Method Not Allowed。我正在尝试发布而不是获取,所以我对为什么会发生这种情况感到困惑;并且其他参数(代码和主机)不显示。我假设代码和主机密钥会出现在 create 方法中,但事实并非如此。我还想补充一点,无论更改序列化程序以将 id、代码和主机添加到序列化程序,还是按照屏幕截图中的方式保留代码,我都会收到完整性错误。

models.py

from django.db import models
import random
import string

# Create your models here.

def code():
    """
    function randomly creates room access code
    """
    length = 7

    while True:
        code = ''.join(random.choices(string.ascii_uppercase + string.digits, k=length))
        if Room.objects.filter(code=code).count() == 0:
            break

        return code
        
class Room(models.Model):
    """
    sets up room requirements and stores it as a model
    """
    code            = models.CharField(max_length=10, default=code,
                                        unique=True)
    host            = models.CharField(max_length=50, unique=True)
    guest_can_pause = models.BooleanField(null=False, default=False)
    votes_to_skip   = models.IntegerField(null=False, default=1)
    created_at      = models.DateTimeField(auto_now_add=True)

序列化器.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')

views.py

from django.shortcuts import render
from .models import Room
from .serializers import RoomSerializer, CreateRoomSerializer, UpdateRoomSerializer
from django.http import JsonResponse
from rest_framework.views import APIView
from rest_framework.response import Response
from rest_framework import generics, status


# Create your views here.

class RoomView(generics.ListAPIView):
    """
    collects all parameters from a serializer to show an existing room
    """
    queryset = Room.objects.all()
    serializer_class = RoomSerializer


class CreateRoomView(APIView):
    """
    creates a room using the POST method and accesses the serializer for the
    parameters
    """
    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['guest_can_pause']
            votes_to_skip = serializer.data['votes_to_skip']
            host = self.request.session.session_key
            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)

【问题讨论】:

  • 你能把代码作为代码而不是截图吗?
  • 使用邮递员,那么你不会得到任何错误,因为如果你在浏览器中传递 URL,它总是(GET)只是这样说

标签: python django rest django-rest-framework


【解决方案1】:

如果您希望 get 和 post 方法与视图一起使用,请尝试使用 class CreateRoomView(generics.ListCreateApiView): 而不是这个 class CreateRoomView(APIView):。如果你只想要 post 方法而不是 class CreateRoomView(generics.CreateAPIView):

【讨论】:

  • 不改变输出,第二个给出断言错误。感谢您的回复。
  • 这不是错误,因为当您打开 api url 时,浏览器会发出 get 请求,正如 Dev Kumar 提到的那样。您应该使用 postman 或 curl 等工具来测试您的 api 视图
  • 谢谢。感谢您的回复。
【解决方案2】:

这实际上是由于您的浏览器在您打开当前 URL 时向您的服务器发出的第一个请求,它是一个 get 请求,因为如果不允许,则服务器响应为 get。

如果您仍然想要一个 get 方法,请尝试使用 modelViewset,它们非常棒且非常灵活,请阅读此文档。 https://www.django-rest-framework.org/api-guide/viewsets/

【讨论】:

  • 我该如何解决这个问题?
  • 如果你愿意,你可以向基于类的视图添加一个 get 方法,但我不需要它,只需忽略它,因为它不会妨碍其他人使用你的 API。
  • @triedit 如果您仍想修复它,请为视图编写 get 方法或使用任何具有所有这些方法默认值的模型视图集,通过 modeviewset,您会没事的。
【解决方案3】:

POSTMAN 中的 POST 请求可以在重定向期间转换为 GET 并给您 HTTP 405 错误: { "detail": "不允许使用方法 "GET"。" }

。为避免这种情况,您可以转到请求中的设置(Params, Auth.. 附近),然后在以下项目中单击 OFF 到 ON:

Follow original HTTP Method -> 点击开启 使用原始 HTTP 方法进行重定向,而不是使用 GET 进行重定向的默认行为。

Follow Authorization header -> 点击 ON 当重定向发生在不同的主机名时保留授权标头。

【讨论】:

    猜你喜欢
    • 2018-03-02
    • 2021-07-01
    • 1970-01-01
    • 2021-02-19
    • 1970-01-01
    • 2018-12-22
    • 1970-01-01
    • 2018-07-21
    • 2019-04-10
    相关资源
    最近更新 更多