我正在尝试创建一个REST API来注册新用户,我正在使用Django REST Framework并使用AngularJS调用API:
当我使用POST methond调用API时,我收到此错误
方法不允许(POST):/ api/v1/accounts
这是我的代码:
views.py
from rest_framework import permissions, viewsets, status, views from django.contrib.auth import authenticate, login, logout from authentication.serializers import AccountSerializer from authentication.permissions import IsAccountOwner from rest_framework.response import Response from authentication.models import Account import json 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.objects.create_user(**serializer.validated_data) return Response(serializer.validated_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)
serialisers.py
from django.contrib.auth import update_session_auth_hash from rest_framework import serializers from authentication.models import Account class AccountSerializer(serializers.ModelSerializer): password = serializers.CharField(write_only=True, required=False) confirm_password = serializers.CharField(write_only=True, required=False) class Meta: model = Account fields = ('id', 'email', 'username', 'created_at', 'updated_at', 'first_name', 'last_name', 'tagline', 'password', 'confirm_password',) read_only_fields = ('created_at', 'updated_at',) def create(validated_data): return Account.objects.create(**validated_data) def update(self, instance, validated_data): instance.username = validated_data.get('username', instance.username) instance.tagline = validated_data.get('tagline', instance.tagline) instance.save() password = validated_data.get('password', None) confirm_password = validated_data.get('confirm_password', None) if password and confirm_password and password == confirm_password: instance.set_password(password) instance.save() update_session_auth_hash(self.context.get('request'), instance) return instance
permissions.py
from rest_framework import permissions class IsAccountOwner(permissions.BasePermission): def has_object_permission(self, request, view, account): if request.user: return account == request.user return False
urls.py
from authentication.views import LoginView, LogoutView from posts.views import AccountPostsViewSet, PostViewSet from authentication.views import AccountViewSet from rest_framework_nested import routers from django.conf.urls import url, include from django.contrib import admin from CVC.views import IndexView router = routers.SimpleRouter() router.register(r'accounts', AccountViewSet) router.register(r'posts', PostViewSet) accounts_router = routers.NestedSimpleRouter( router, r'accounts', lookup='account' ) accounts_router.register(r'posts', AccountPostsViewSet) urlpatterns = [ url(r'^api/v1/auth/login/$', LoginView.as_view(), name='login'), url(r'^api/v1/auth/logout/$', LogoutView.as_view(), name='logout'), url('^.*$', IndexView.as_view(), name='index'), url(r'^admin/', admin.site.urls), url(r'^api/v1/', include(router.urls)), url(r'^api/v1/', include(accounts_router.urls)),
register.controller.js
(function () { 'use strict'; angular .module('thinkster.authentication.controllers') .controller('RegisterController', RegisterController); RegisterController.$inject = ['$location', '$scope', 'Authentication']; function RegisterController($location, $scope, Authentication) { var vm = this; activate(); vm.register = register; function register() { Authentication.register(vm.email, vm.password, vm.username); } function activate() { if (Authentication.isAuthenticated()) { $location.url('/'); } } } })();
authentication.service.js
(function () { 'use strict'; angular .module('thinkster.authentication.services') .factory('Authentication', Authentication); Authentication.$inject = ['$cookies', '$http']; function Authentication($cookies, $http) { var Authentication = { getAuthenticatedAccount: getAuthenticatedAccount, setAuthenticatedAccount: setAuthenticatedAccount, isAuthenticated: isAuthenticated, login: login, logout: logout, register: register, unauthenticate: unauthenticate }; return Authentication; function register(email, password, username) { return $http.post('/api/v1/accounts', { email: email, password: password, username: username }).then(registerSuccessFn, registerErrorFn); function registerSuccessFn(data, status, headers, config) { Authentication.login(email, password); } function registerErrorFn(data, status, headers, config) { console.error('Epic failure!'); } } function login(email, password) { return $http.post('/api/v1/auth/login/', { email: email, password: password }).then(loginSuccessFn, loginErrorFn); function loginSuccessFn(data, status, headers, config) { Authentication.setAuthenticatedAccount(data.data); window.location = '/'; } function loginErrorFn(data, status, headers, config) { console.error('Epic failure!'); } } function logout() { return $http.post('/api/v1/auth/logout/') .then(logoutSuccessFn, logoutErrorFn); function logoutSuccessFn(data, status, headers, config) { Authentication.unauthenticate(); window.location = '/'; } function logoutErrorFn(data, status, headers, config) { console.error('Epic failure!'); } } function getAuthenticatedAccount() { if (!$cookies.authenticatedAccount) { return; } return JSON.parse($cookies.authenticatedAccount); } function isAuthenticated() { return !!$cookies.authenticatedAccount; } function setAuthenticatedAccount(account) { $cookies.authenticatedAccount = JSON.stringify(account); } function unauthenticate() { delete $cookies.authenticatedAccount; } } })();
我是Django和AnglarJS的新手,所以我不知道哪个部分导致了这个问题?
您在URL映射中不需要路由器,除非您有以下操作以外的自定义操作:
def list(self, request):
pass
def create(self, request):
pass
def retrieve(self, request, pk=None):
pass
def update(self, request, pk=None):
pass
def partial_update(self, request, pk=None):
pass
def destroy(self, request, pk=None):
pass
将其添加到views.py:
account_list = AccountViewSet.as_view({
'get': 'list',
'post': 'create'
})
在urls.py中:
url(r'^account/$', account_list, name='account-list'),