riz*_*tas 2 django django-rest-framework
我正在编写一个插件包装器来提供一个应用程序来休息,问题是应用程序不处理PUT请求,然后我从resfull得到一个PUT请求并应该将请求的方法更改为POST请求.
我试过这个:
self.context['request'].method = 'POST'
Run Code Online (Sandbox Code Playgroud)
但显然不起作用
我怎么能这样做?谢谢
串行器代码:
class PageEditSerializer(serializers.ModelSerializer):
"""
Serializer Class to edit and delete a Page.
"""
raw = serializers.CharField()
def save(self):
#no works
self.context['request'].method = 'POST'
"""call to waliki new function"""
views.edit(self.context['request'], self.instance.slug)
class Meta():
model = Page
fields = ('id', 'title', 'slug', 'raw', )
read_only_fields = ('id', 'slug', )
Run Code Online (Sandbox Code Playgroud)
查看代码:
class PageEditView(generics.RetrieveUpdateAPIView):
"""
A simple View to edit a Page.
"""
lookup_field = 'slug'
serializer_class = PageEditSerializer
permission_classes = (permissions.AllowAny, )
def get_queryset(self):
return Page.objects.filter(slug=self.kwargs['slug'])
Run Code Online (Sandbox Code Playgroud)
我将把答案分成3部分.
第1部分:DRF是否明确支持请求方法覆盖?
是的,DRF提供了两种可以覆盖请求方法的方法.
DRF支持基于浏览器的PUT,DELETE和其他的方法,通过超载POST使用隐藏的表单字段的请求.
例如:
<form action="/some/url" method="POST">
<input type="hidden" name="_method" value="PUT">
</form>
Run Code Online (Sandbox Code Playgroud)
在上面的示例中,我们使用名称为的隐藏表单字段重载了POST方法.PUT_method
request.method现在将返回PUT而不是POST.
DRF还支持通过X-HTTP-Method-Override标头覆盖方法.只需X-HTTP-Method-Override使用所需方法的值设置标题即可.
例如,PATCH通过POSTjQuery 发出请求:
$.ajax({
url: '/myresource/',
method: 'POST',
headers: {'X-HTTP-Method-Override': 'PATCH'},
...
});
Run Code Online (Sandbox Code Playgroud)
在处理非形式内容(如JSON)或处理较旧的Web服务器和/或无法识别特定HTTP方法的托管提供程序时,此方法非常有用PATCH.
第2部分:为什么你的代码不起作用?
请求方法存储在变量中_method,该属性method用于访问它的值.
如果已经setter为请求的_method属性定义了,那么设置请求方法值的方法就会有效.由于未定义,因此无法method以您的方式设置请求值.
第3部分:如何覆盖您案例中的请求方法?
Solution-1(快速):直接设置_method属性
您可以直接将_method所需值设置为覆盖请求方法的所需值.
class PageEditSerializer(serializers.ModelSerializer):
"""
Serializer Class to edit and delete a Page.
"""
raw = serializers.CharField()
def save(self):
self.context['request']._method = 'POST' # override the request method
"""call to waliki new function"""
views.edit(self.context['request'], self.instance.slug)
class Meta():
model = Page
fields = ('id', 'title', 'slug', 'raw', )
read_only_fields = ('id', 'slug', )
Run Code Online (Sandbox Code Playgroud)
这将覆盖请求方法POST.
解决方案-2:X-HTTP-Method-Override通过中间件在请求中设置标头
当initialize_request()被称为在DRF视图,DRF检查X-HTTP-Method-Override在Django的请求报头.如果已设置,则它会覆盖当前method对该标头中定义的方法的请求.
因此,在DRF初始化并准备DRF之前request,我们可以将X-HTTP-Method-Override标头设置为我们所需的方法,该方法将覆盖请求方法.
我们创建一个PutRequestMethodOverrideMiddleware类并X-HTTP-Method-Override在请求中设置标头,以防请求,PUT并且尚未设置此特定标头.
class PutRequestMethodOverrideMiddleware(object):
def process_request(self, request):
override_method = request.META.get('X-HTTP-Method-Override')
if request.method=='PUT' and not override_method:
# Override method in case of PUT requests and header not already set
request.META['X-HTTP-Method-Override'] = 'POST' # set to desired method value
return
Run Code Online (Sandbox Code Playgroud)
然后在您的设置中,将此中间件添加到您的MIDDLEWARE_CLASSES.
MIDDLEWARE_CLASSES = (
'django.middleware.common.CommonMiddleware',
'django.middleware.csrf.CsrfViewMiddleware',
...
...
# your custom middleware
'my_project.middlewares.PutRequestMethodOverrideMiddleware',
)
Run Code Online (Sandbox Code Playgroud)
但请记住,此方法将覆盖方法的所有PUT请求POST方法.
在这里,PutRequestMethodOverrideMiddleware将在最后执行.您可以将它放在您希望它执行的位置.
| 归档时间: |
|
| 查看次数: |
4857 次 |
| 最近记录: |