如何使ModelViewSet接受POST方法来创建对象?当我尝试呼叫端点时,我得到405 'Method "POST" not allowed.'
。
在views.py内:
class AccountViewSet(viewsets.ModelViewSet):
"""An Account ModelViewSet."""
model = Account
serializer_class = AccountSerializer
queryset = Account.objects.all().order_by('name')
在serializers.py中:
class AccountSerializer(serializers.ModelSerializer):
name = serializers.CharField(required=False)
active_until = serializers.DateTimeField()
class Meta:
model = Account
fields = [
'name',
'active_until',
]
def create(self, validated_data):
with transaction.atomic():
Account.objects.create(**validated_data)
在urls.py中:
from rest_framework import routers
router = routers.SimpleRouter()
router.register(
prefix=r'v1/auth/accounts',
viewset=AccountViewSet,
base_name='accounts',
)
我需要创建一个特定的@action
吗?我的尝试尚未成功。如果是这种情况,我可以从测试中调用url = reverse('app:accounts-<NAME>')
是什么?我还没有找到完整的示例(urls.py,views.py,serializers.py和测试等)。
答案 0 :(得分:0)
从文档中
ViewSet类只是基于类的View的一种,它不提供任何方法处理程序,例如.get()或.post(),而是提供诸如.list()和.create()的操作。
这是受支持的操作的列表:
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
因此,不直接支持任何帖子,但不支持创建。 因此,当使用路由器而不是v1 / auth / accounts / post时,您的终点将是v1 / auth / accounts / create。
老实说,我更喜欢在使用DRF时使用基于类或基于函数的视图。它与django的常规视图更为相似,与我合作时更有意义。您将非常像常规的Django URL和视图那样编写视图和URL。
答案 1 :(得分:0)
您的代码似乎正常。我认为您正在尝试在另一个端点上创建一个新实例。也就是说,您可能会尝试使用v1/auth/accounts/id
方法请求 HTTP POST
端点,这是不允许的。
因此,将HTTP POST
请求发送到该端点 v1/auth/accounts/
在此处DRF simplerouter
Doc
答案 2 :(得分:0)
我发现了问题所在,路线有冲突。在AccountViewSet之前注册了一个更高级别的终结点。
router.register(
prefix=r'v1/auth',
viewset=UserViewSet,
base_name='users',
)
router.register(
prefix=r'v1/auth/accounts',
viewset=AccountViewSet,
base_name='accounts',
)
router.register(
prefix=r'v1/auth/accounts',
viewset=AccountViewSet,
base_name='accounts',
)
router.register(
prefix=r'v1/auth',
viewset=UserViewSet,
base_name='users',
)
尽管reverse('appname:acccounts-list')
可以正常工作,但底层URL路由器仍然认为我正在调用UserViewSet。