use*_*719 45 django post json django-rest-framework
非常感谢有人向我展示如何使用JSON与Django REST框架进行简单的POST请求.我在教程中没有看到任何这方面的例子吗?
这是我想要POST的我的角色模型对象.这将是一个全新的角色,我想添加到数据库,但我收到500错误.
{
"name": "Manager",
"description": "someone who manages"
}
Run Code Online (Sandbox Code Playgroud)
这是我在bash终端提示符下的curl请求:
curl -X POST -H "Content-Type: application/json" -d '[
{
"name": "Manager",
"description": "someone who manages"
}]'
http://localhost:8000/lakesShoreProperties/role
Run Code Online (Sandbox Code Playgroud)
网址
http://localhost:8000/lakesShoreProperties/roles
Run Code Online (Sandbox Code Playgroud)
是否可以使用GET请求,我可以删除数据库中的所有角色,但我似乎无法创建任何新角色.我没有权限设置.我在views.py中使用标准视图
class RoleDetail(generics.RetrieveUpdateDestroyAPIView):
queryset = Role.objects.all()
serializer_class = RoleSerializer
format = None
class RoleList(generics.ListCreateAPIView):
queryset = Role.objects.all()
serializer_class = RoleSerializer
format = None
Run Code Online (Sandbox Code Playgroud)
在我urls.py的这个应用程序中,相关的URL - 视图映射是正确的:
url(r'^roles/$', views.RoleList.as_view()),
url(r'^role/(?P<pk>[0-9]+)/$', views.RoleDetail.as_view()),
Run Code Online (Sandbox Code Playgroud)
错误信息是:
{
"detail": "CSRF Failed: CSRF token missing or incorrect."
}
Run Code Online (Sandbox Code Playgroud)
这里发生了什么,这是什么解决方案?localhost是否是跨站点请求?我添加@csrf_exempt了RoleDetail,RoleList但它似乎没有改变任何东西.这个装饰器甚至可以添加到类中,还是必须添加到方法中?添加@csrf_exempt装饰,我的错误变为:
Request Method: POST
Request URL: http://127.0.0.1:8000/lakeshoreProperties/roles/
Django Version: 1.5.1
Exception Type: AttributeError
Exception Value:
'function' object has no attribute 'as_view'
Run Code Online (Sandbox Code Playgroud)
然后我通过整个应用程序禁用了CSRF,现在我收到此消息:
{"non_field_errors":["无效数据"]}当我知道的JSON对象是有效的json时.这是一个非现场错误,但我被困在这里.
好吧,事实证明我的json无效?
{
"name": "admin",
"description": "someone who administrates"
}
Run Code Online (Sandbox Code Playgroud)
VS
[
{
"name": "admin",
"description": "someone who administrates"
}
]
Run Code Online (Sandbox Code Playgroud)
使用括号[],会导致POST请求失败.但是使用jsonlint.com验证器,我的两个json对象都会验证.
更新:问题在于使用PostMan发送POST,而不是在后端发送.请参阅/sf/answers/1225589431/
Ter*_*Lam 34
在Django REST Framework中默认免除CSRF.因此,curl POST请求工作正常.POSTMAN请求调用返回CSRF不正确,因为POSTMAN包含csrf令牌(如果在Cookie中找到它).您可以通过清理Cookie来解决此问题.
小智 24
它来自您的REST Framework设置.在您的settings.py文件中,您REST_FRAMEWORK应该具有以下内容.
REST_FRAMEWORK = {
'DEFAULT_AUTHENTICATION_CLASSES': (
'rest_framework.authentication.TokenAuthentication',
),
'DEFAULT_PERMISSION_CLASSES': (
'rest_framework.permissions.AllowAny',
),
}
Run Code Online (Sandbox Code Playgroud)
这将使您的REST Framework设置为使用令牌身份验证而不是csrf身份验证.通过设置权限AllowAny,您可以只在您想要的位置进行身份验证.
ste*_*iot 10
您可能需要使用您的请求发送CSRF令牌.查看https://docs.djangoproject.com/en/1.7/ref/contrib/csrf/#csrf-ajax
更新:因为您已经尝试过免除CSRF,这可能有所帮助(取决于您使用的Django版本):https://stackoverflow.com/a/14379073/977931
use*_*719 10
好吧,现在当然我收回我所说的话.CSRF确实按预期工作.
我正在使用名为POSTMAN的chrome插件发出POST请求.我的POST请求失败并启用了CSRF.
但是使用curl POST请求
curl -X POST -H "Content-Type: application/json" -d '
{
"name": "Manager",
"description": "someone who manages"
}' http://127.0.0.1:8000/lakeshoreProperties/roles/
Run Code Online (Sandbox Code Playgroud)
工作正常...我不得不取下大括号,即[],并确保角色中的's'后面有一个斜杠,即roles /,并且csrf启用时没有抛出任何错误.
我不确定使用POSTMAN调用vs使用curl之间有什么区别,但POSTMAN是在Web浏览器中运行的,这是最大的区别.也就是说,我为整个类RoleList禁用了csrf,但是一个相同的请求与Curl一起使用,但是使用POSTMAN失败了.