我有一个简单的DRF列表视图,想写一些与POST
请求有关的权限。发出GET
请求时导致错误。这使我意识到,对未提交的请求多次调用了我的权限类。这是我的文件。
permissons.py:
class IsDummy(permissions.BasePermission):
def has_permission(self, request, view):
print("\n{}\n".format(request.method))
if request.method in permissions.SAFE_METHODS:
return True
return False
views.py:
class UserListView(generics.ListCreateAPIView):
queryset = User.objects.all()
serializer_class = UserSerializer
permission_classes = [IsDummy]
仅当我通过浏览器在可浏览api上提交请求时,才会发生此问题。当我在列表URL上提交GET请求时,我将从IsDummy
权限类中的print语句向终端打印以下内容:
GET
POST
POST
OPTIONS
当我通过邮递员提交GET
或OPTIONS
请求时,我会看到我实际使用的单个适当的请求方法。
似乎列出的第一个方法始终是我使用的实际方法,我不知道多余的POST
和OPTION
来自何处。甚至更奇怪的是,即使POST
请求显然应该导致IsDummy.has_permission
返回False
,页面也会在所有这些之后正常加载。
chrome开发工具仅显示一个提交的GET
请求,由于该请求似乎只在可浏览的api中发生,因此我敢肯定它与此有关,但我不知道自己在做什么搞砸了,使之成为现实。
答案 0 :(得分:3)
浏览器api是一个Signed页面,可以添加\ update \ delete实例,当您询问该页面时,drf将检查所有必需的权限,以查看相应模块是否需要显示。
深入了解drf源代码,您可以在renderers.py
中看到它:
class BrowsableAPIRenderer(BaseRenderer):
"""
HTML renderer used to self-document the API.
"""
media_type = 'text/html'
format = 'api'
template = 'rest_framework/api.html'
filter_template = 'rest_framework/filters/base.html'
code_style = 'emacs'
charset = 'utf-8'
form_renderer_class = HTMLFormRenderer
...
def get_context(self, data, accepted_media_type, renderer_context):
....
context = {
....
'put_form': self.get_rendered_html_form(data, view, 'PUT', request),
'post_form': self.get_rendered_html_form(data, view, 'POST', request),
'delete_form': self.get_rendered_html_form(data, view, 'DELETE', request),
'options_form': self.get_rendered_html_form(data, view, 'OPTIONS', request),
}
return context
def get_rendered_html_form(self, data, view, method, request):
....
if not self.show_form_for_method(view, method, request, instance):
....
def show_form_for_method(self, view, method, request, obj):
"""
Returns True if a form should be shown for this method.
"""
if method not in view.allowed_methods:
return # Not a valid method
try:
view.check_permissions(request)
if obj is not None:
view.check_object_permissions(request, obj)
except exceptions.APIException:
return False # Doesn't have permissions
return True
view.check_permissions(request)
中的 show_form_for_method
是为什么DRF可浏览API针对每个实际请求对多种请求类型运行权限检查的原因