【问题标题】:HTTP/1.0 301 Moved Permanently-DjangoHTTP/1.0 301 永久移动-Django
【发布时间】:2017-04-28 09:06:25
【问题描述】:

我使用 djangorestframework 创建了一个 API,但是当我在终端中使用 python manage.py runserver 命令运行它时,它显示“HTTP/1.0 301 Moved Permanently”错误。This the Message which it shows p>

但很酷的是,当我在浏览器中运行它时,它会显示数据。 This the result in Chrome

我想知道发生了什么事。

在此 POST 调用也不起作用。

下面是代码:

serializers.py

from rest_framework import serializers
from snippets.models import Snippet

class SnippetSerializer(serializers.ModelSerializer):
            class Meta:
                model = Snippet
                fields = ('title','code',)

def create(self, validated_data):
    return Snippet.objects.create(**validated_data)


def update(self, instance, validated_data):
    instance.title = validated_data.get('title', instance.title)
    instance.code = validated_data.get('code', instance.code)
    instance.save()
    return instance

Views.py

from django.shortcuts import render
from django.http import HttpResponse
from django.views.decorators.csrf import csrf_exempt
from rest_framework.renderers import JSONRenderer
from rest_framework.parsers import JSONParser
from snippets.models import Snippet
from snippets.serializers import SnippetSerializer


# Create your views here.


class JSONResponse(HttpResponse):
    def __init__(self,data,**kwargs):
        content = JSONRenderer().render(data)
        kwargs['content_type']='application/json'
        super(JSONResponse, self).__init__(content, **kwargs)

@csrf_exempt
def snippet_list(request):
    """
    List all code snippets, or create a new snippet.
    """
    if request.method == 'GET':
        snippets = Snippet.objects.all()
        serializer = SnippetSerializer(snippets, many=True)
        return JSONResponse(serializer.data)

    elif request.method == 'POST':
        data = JSONParser().parse(request)
        serializer = SnippetSerializer(data=data)
        if serializer.is_valid():
            serializer.save()
            return JSONResponse(serializer.data, status=201)
        return JSONResponse(serializer.errors, status=400)

@csrf_exempt
def snippet_detail(request, pk):
    """
    Retrieve, update or delete a code snippet.
    """
    try:
        snippet = Snippet.objects.get(pk=pk)
    except Snippet.DoesNotExist:
        return HttpResponse(status=404)

    if request.method == 'GET':
        serializer = SnippetSerializer(snippet)
        return JSONResponse(serializer.data)

    elif request.method == 'PUT':
        data = JSONParser().parse(request)
        serializer = SnippetSerializer(snippet, data=data)
        if serializer.is_valid():
            serializer.save()
            return JSONResponse(serializer.data)
        return JSONResponse(serializer.errors, status=400)

    elif request.method == 'DELETE':
        snippet.delete()
        return HttpResponse(status=204)

模型.py

from __future__ import unicode_literals

from django.db import models

# Create your models here.


class Snippet(models.Model):
    created = models.DateTimeField(auto_now_add=True)
    title = models.CharField(max_length=100, blank=True, default='')
    code = models.TextField()


class Meta:
    ordering = ('created',)

【问题讨论】:

    标签: django python-2.7 django-models django-views django-rest-framework


    【解决方案1】:

    301 不是错误,而是重定向。在命令行中,您请求了一个不带斜杠的 URL,但您的 URL 模式希望斜杠存在。 Django 有一个很好的convenience feature 在这种情况下返回重定向。

    与您的命令行 HTTP 客户端不同,您的浏览器会识别重定向,然后跟进对新 URL 的第二次请求,包括尾部斜杠。

    【讨论】:

    • 但是@koniiiik 我无法使用邮递员在上面发布数据
    • 你需要post到包含斜杠的URL,没有斜杠的总是返回重定向,忽略请求正文。
    【解决方案2】:

    您看到的效果是因为您的 URL 以 / 结尾映射,而您请求的链接没有以 / 结尾。默认情况下,如果找不到与请求的 URL 匹配的 URL,Django 将尝试以 / 结尾的 URL。

    这由APPEND_SLASH 设置控制,默认设置为True

    当设置为 True 时,如果请求 URL 不匹配任何 URLconf 中的模式,它不以斜杠结尾,一个 HTTP 将重定向发送到附加了斜杠的相同 URL。注意 重定向可能会导致在 POST 请求中提交的任何数据 丢了。

    要解决此问题,请将您的命令更改为:

    http http://127.0.0.1:8006/snippets/
    

    【讨论】:

      【解决方案3】:

      您似乎已将 APPEND_SLASH 设置为 true。当您转到没有斜杠的端点时,它会自动将其重定向到带有斜杠的相同 URL,从而导致 301。

      Documentation is here.

      【讨论】:

      • 呸,忍者对它!
      【解决方案4】:

      https://www.django-rest-framework.org/api-guide/routers/

      "默认情况下,SimpleRouter 创建的 URL 会附加一个斜杠。在实例化路由器时,可以通过将 trailing_slash 参数设置为 False 来修改此行为。例如:

      router = SimpleRouter(trailing_slash=False)
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2016-07-04
        • 1970-01-01
        • 2019-11-04
        • 2012-07-10
        • 2013-09-26
        • 2019-10-14
        相关资源
        最近更新 更多