不允许使用 Django Angularjs 405 方法。 thinkster.io 教程

Posted

技术标签:

【中文标题】不允许使用 Django Angularjs 405 方法。 thinkster.io 教程【英文标题】:Django Angularjs 405 method not allowed. thinkster.io tutorial 【发布时间】:2015-02-03 01:41:10 【问题描述】:

我正在浏览位于以下位置的教程:

https://thinkster.io/brewer/angular-django-tutorial/

我已经完成了大约 1/3-1/2。我现在正在测试它是否会注册用户。不会的,每次我提交它给我POST http://127.0.0.1:8000/api/v1/accounts/ 405 (METHOD NOT ALLOWED) 的表单时,我都会跑回同一个教程六次,看看我的错误在哪里,但我似乎找不到它。

我不是 %100 肯定问题出在哪里,所以我会发布最有可能出现问题的代码文件。

authentication/views.py

from django.shortcuts import render

from rest_framework import permissions, viewsets

from authentication.models import Account
from authentication.permissions import IsAccountOwner
from authentication.serializers import AccountSerializer


class AccountViewSet(viewsets.ModelViewSet):
    lookup_field = 'username'
    queryset = Account.objects.all()
    serializer_class = AccountSerializer

    def get_permissions(self):
        if self.request.method in permissions.SAFE_METHODS:
            return (permissions.AllowAny(),)

        if self.request.method == 'POST':
            return (permissions.AllowAny(),)

        return (permissions.IsAuthenticated(), IsAccountOwner(),)

    def create(self, request):
        serializer = self.serializer_class(data=request.DATA)

        if serializer.is_valid():
            account = Account.objects.create_user(**request.DATA)

            account.set_password(request.DATA.get('password'))
            account.save()

            return Response(serializer.data, status=status.HTTP_201_CREATED)
        return Response(
            'status': 'Bad request',
            'message': 'Account could not be created with received data.'
        , status=status.HTTP_400_BAD_REQUEST)

static/javascripts/authentication.service.js

/**
* Authentication
* @namespace thinkster.authentication.services
*/
(function () 
    'use strict';

    angular
        .module('thinkster.authentication.services')
        .factory('Authentication', Authentication);

    Authentication.$inject = ['$cookies', '$http'];

    /**
    * @namespace Authentication
    * @returns Factory
    */
    function Authentication($cookies, $http) 
        /**
        * @name Authentication
        * @desc The Factory to be returned
        */
        var Authentication = 
            register: register
        ;

        return Authentication;

        ////////////////////

        /**
        * @name register
        * @desc Try to register a new user
        * @param string username The username entered by the user
        * @param string password The password entered by the user
        * @param string email The email entered by the user
        * @returns Promise
        * @memberOf thinkster.authentication.services.Authentication
        */
        function register(username, password, email) 
            return $http.post('/api/v1/accounts/', 
                username: username,
                password: password,
                email: email
            );
        
    
)();

static/templates/register.html

<div class="row">
    <div class="col-md-4 col-md-offset-4">
        <h1>Register</h1>

        <div class="well">
            <form role="form" ng-submit="vm.register()">
                <div class="form-group">
                    <label for="register__email">Email</label>
                    <input type="email" class="form-control" id="register__email" ng-model="vm.email" placeholder="ex. john@notgoogle.com" />
                </div>

                <div class="form-group">
                    <label for="register__username">Username</label>
                    <input type="text" class="form-control" id="register__username" ng-model="vm.username" placeholder="ex. john" />
                </div>

                <div class="form-group">
                    <label for="register__password">Password</label>
                    <input type="password" class="form-control" id="register__password" ng-model="vm.password" placeholder="ex. thisisnotgoogleplus" />
                </div>

                <div class="form-group">
                    <button type="submit" class="btn btn-primary">Submit</button>
                </div>
            </form>
        </div>
    </div>
</div>

最后一个:

static/javascripts/register.controller.js

/**
* Register controller
* @namespace thinkster.authentication.controllers
*/
(function () 
    'use strict';

    angular
        .module('thinkster.authentication.controllers')
        .controller('RegisterController', RegisterController);

    RegisterController.$inject = ['$location', '$scope', 'Authentication'];

    /**
    * @namespace RegisterController
    */
    function RegisterController($location, $scope, Authentication) 
        var vm = this;

        vm.register = register;

        /**
        * @name register
        * @desc Register a new user
        * @memberOf thinkster.authentication.controllers.RegisterController
        */
        function register() 
            Authentication.register(vm.email, vm.password, vm.username);
        
    
)();

而且,如果这还不够代码,项目也存储在:https://github.com/Taylor-Allred/thinkster-django-angular-boilerplate

我为文字/代码墙道歉,任何帮助将不胜感激。

【问题讨论】:

【参考方案1】:

我在测试新帖子提交时遇到了同样的问题。

在搜索了我的代码之后,我终于在我的posts.service.js 中找到了这个:

function create (content) 
        return $http.post('/api/v1/posts', 
            content: content
        );

您会注意到 POST 请求中缺少 /。我把它改成:

return $http.post('/api/v1/posts/', ...

现在一切都恢复正常了。

【讨论】:

【参考方案2】:

抱歉(不可接受的)延迟响应!不知道我是怎么错过你的问题的,但我想迟到的答案总比没有答案好。

如果您查看您的urls.py 文件,您会注意到您有两条包罗万象的路线。请删除第一个。包罗万象的路由必须始终是 urls.py 文件中的最后一条路由,特别是您遇到此错误的原因。

这是怎么回事:

当您发出请求 POST /api/v1/accounts/ 时,Django 会将此与您的 urls.py 文件中的第一个包罗万象的路由进行匹配。这会将请求转发到IndexView,请求期望在其中提交post() 方法。 IndexView 没有post() 方法,因此请求失败,状态码为405

尽管这是一个很晚的回复,但我希望这对您有所帮助。

如果我不清楚,请随时评论这个答案!

附: olsonk 有一点关于以与您的代码不兼容的方式注册接受的参数。另外,距离我写教程已经过去了一段时间。此时,DRF(Django REST Framework)已更新,因此代码可能无法按原样运行。

【讨论】:

我已经按照相同的教程在 django 和 angularJs 中创建了一个注册方法,但不幸的是我无法访问 localhost:8000/register url,我在这里遇到一个错误 "name 'IndexView' is not defined" 表示 url('^.*$', IndexView.as_view(), name='index') 的 urls.py 文件, 存在。我真的很失望。 很抱歉让您失望了。我的猜测是IndexView 缺少导入语句。【参考方案3】:

我不确定这是否能解决问题,但我确实注意到了一个潜在问题 - 您的 RegisterControllerregister() 方法以与您的 Authentication 服务的 register() 方法不同的顺序发送您的参数。您的服务期望接收(用户名、密码、电子邮件),但您的控制器发送(电子邮件、密码、用户名)。

我在教程中也遇到了 405 错误,但我的错误与我的 authentication.service 发布到 '/api/v1/register/' 而不是 '/api/v1/accounts' 有关。一旦我完成了这项工作,我就不得不在authentication/views.py - from rest_framework import statusfrom rest_framework.response import Response 中添加更多导入。

我也在摸索自己的方式来学习这些东西,这是我对 StackExchange 的第一次回复,所以如果这对您没有帮助/不能完全解决您的问题,我深表歉意。

【讨论】:

感谢您的回复,今晚晚些时候我会尝试一下。 仅供参考 - 我今天完成了教程并让它(几乎完全)工作;现在唯一的问题是帖子有时不会在个人资料视图上呈现。项目位于https://github.com/olsonk/thinkster-django-angular-boilerplate.git。希望对您有所帮助 - 我在整个模板中发现了几个错误,这些错误需要很长时间才能找到并修复,因此它可以用作双重检查源。

以上是关于不允许使用 Django Angularjs 405 方法。 thinkster.io 教程的主要内容,如果未能解决你的问题,请参考以下文章

URLrewrite后不允许AngularJS / c#WebAPI 405方法

电子邮件验证和密码重置 - django rest 框架和 angularjs

Django 不使用 Angularjs

Django/DRF - 405 方法不允许删除操作

与 AngularJS 一起使用时,Django 模板不呈现 JSON 响应

angularjs 和 PHP:预检响应中的 Access-Control-Allow-Headers 不允许请求标头字段 Access-Control-Allow-Origin