Python DRF request.data没有属性_可变
我正在使用Django 2.x和Django REST框架 我正在使用Python DRF request.data没有属性_可变,python,django,django-rest-framework,django-rest-auth,django-oauth,Python,Django,Django Rest Framework,Django Rest Auth,Django Oauth,我正在使用Django 2.x和Django REST框架 我正在使用django oauth toolkit来启用OAuth2身份验证和django rest auth进行登录和django allauth进行用户注册 我想在用户成功注册时在响应中生成访问令牌。为此,我使用了自定义注册视图 为此,我创建了一个函数utils,如 def generate_token(request, user): # Get OAuth application to use applicatio
django oauth toolkit
来启用OAuth2
身份验证和django rest auth
进行登录和django allauth
进行用户注册
我想在用户成功注册时在响应中生成访问令牌。为此,我使用了自定义注册视图
为此,我创建了一个函数utils,如
def generate_token(request, user):
# Get OAuth application to use
application_: Application = Application.objects.filter(
client_type=Application.CLIENT_CONFIDENTIAL,
authorization_grant_type=Application.GRANT_PASSWORD
).first()
if not application_:
raise Exception('No OAuth2 Application is setup')
auth_data = {
'username': user.username,
'password': password,
'grant_type': 'password',
'client_id': application_.client_id,
'client_secret': application_.client_secret
}
if request.data:
mutable = request.data._mutable
request.data._mutable = True
request.data.update(auth_data)
request.data._mutable = mutable
if request.POST:
mutable = request.POST._mutable
request.POST._mutable = True
request.POST.update(auth_data)
request.POST._mutable = mutable
return TokenView().create_token_response(request=request)
当端点被邮递员击中时,它工作正常,请求。数据
具有\u可变
属性
但当它被角度应用击中时,会产生误差
'dict' object has no attribute '_mutable'
错误指向mutable=request.data.\u mutable
为什么某些请求缺少\u mutable
编辑2:请求头
邮递员发送的请求标头为
Content-Type:"application/json"
Accept:"application/json, text/plain, /"
User-Agent:"PostmanRuntime/7.15.2"
Cache-Control:"no-cache"
Postman-Token:"b4461728-a6a9-48da-a4fa-3894920b5484"
Host:"api.staging.scanova.io"
Cookie:"messages="660481c3ce8c48b1884641ffdec0a3f701cdc9cf$..."; csrftoken=tNa6o6RDkEUTBti1cDJCvgV5oLG84qczgADeDfSY7hROsLP6cmhIgQKaamPQU7Xy; sessionid=r0l8kh58n8i14quyemj60ur6i59uhy1i"
Accept-Encoding:"gzip, deflate"
Content-Length:635
Connection:"keep-alive"
来自Angular的请求标头为
Accept: application/json, text/plain, */*
Authorization: false false
Content-Type: application/json
Origin: https://localhost:4200
Referer: https://localhost:4200/auth/register
User-Agent: Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/74.0.3729.131 Safari/537.36
编辑3:请求类型
从端点调用的主视图是CreateAPIView
generate_token
从该视图调用,该视图使用TokenView
生成访问令牌。TokenView
为后代使用Django的通用视图
(尽管这个问题很老):
django/DRF似乎以不同的方式处理多部分/表单数据
和应用程序/json
内容类型,从而引发问题
因此,即使使用相同的端点(viewset),并且取决于表单是以多部分还是app/json-请求的形式发送。data
也将是不同的对象
在一种情况下,它将是“正常”dict,而在另一种情况下,它将是QueryDict
类型。因此,为了使用hacky\u mutable
打开/关闭,需要进行与此类似的额外检查:
...
# one can also use:
# if 'multipart/form-data' in request.META.get('CONTENT_TYPE'):
# instead of the condition below
if isinstance(request.data, QueryDict):
auth_data = json.dumps(auth_data) # <----- QueryDict expects string values
request.POST._mutable = True # <----- mutable needs to be modified on POST and not on data
request.data.update(auth_data)
request.POST._mutable = False
...
。。。
#还可以使用:
#如果request.META.get('CONTENT\u TYPE')中的“多部分/表单数据”:
#而不是下面的条件
如果存在(request.data,QueryDict):
auth_data=json.dumps(auth_data)#为后代(尽管这个问题已经很老了):
django/DRF似乎以不同的方式处理多部分/表单数据
和应用程序/json
内容类型,从而引发问题
因此,即使使用相同的端点(viewset),并且取决于表单是以多部分还是app/json-请求的形式发送。data
也将是不同的对象
在一种情况下,它将是“正常”dict,而在另一种情况下,它将是QueryDict
类型。因此,为了使用hacky\u mutable
打开/关闭,需要进行与此类似的额外检查:
...
# one can also use:
# if 'multipart/form-data' in request.META.get('CONTENT_TYPE'):
# instead of the condition below
if isinstance(request.data, QueryDict):
auth_data = json.dumps(auth_data) # <----- QueryDict expects string values
request.POST._mutable = True # <----- mutable needs to be modified on POST and not on data
request.data.update(auth_data)
request.POST._mutable = False
...
。。。
#还可以使用:
#如果request.META.get('CONTENT\u TYPE')中的“多部分/表单数据”:
#而不是下面的条件
如果存在(request.data,QueryDict):
auth_data=json.dumps(auth_data)#我使用了(request.POST._mutable=True),这种方式对我不起作用。
然后我将request.POST复制到一个新变量中,并在我的整个代码中使用新变量,这种方式工作正常(request.POST.\u mutable=True),但这种方式不适用于我。
然后我将request.POST复制到一个新变量中,并在整个代码中使用新变量,这样可以很好地工作在angular中执行什么HTTP类型的请求?获取、发布等?其POST
。在这两种情况下都更新了带有请求头的问题。您的请求
对象的类型是什么?Django的HttpRequest
或DRF的请求
?由于请求通过REST框架,因此其DRF的请求
。如果是HttpRequest
,那么request.POST
将代替request.data
工作。我的意思是,您的TokenView
是什么类型的?我猜您需要切换if语句并将if-request.data
编辑为elif-request.data
,因为您收到的请求可能是django的HttpRequest
类型。您在angular中执行的HTTP类型请求是什么?获取、发布等?其POST
。在这两种情况下都更新了带有请求头的问题。您的请求
对象的类型是什么?Django的HttpRequest
或DRF的请求
?由于请求通过REST框架,因此其DRF的请求
。如果是HttpRequest
,那么request.POST
将代替request.data
工作。我的意思是,您的TokenView
是什么类型的?我猜您需要切换if语句并将if-request.data
编辑为elif-request.data
,因为您收到的请求可能是django的HttpRequest
类型。