为什么DRF可浏览API针对每个实际请求在多个请求类型上运行权限检查? [英] Why is DRF browsable API running permission checks on multiple request types for every actual request?

查看:116
本文介绍了为什么DRF可浏览API针对每个实际请求在多个请求类型上运行权限检查?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个简单的DRF列表视图,想写一些与 POST 请求有关的权限。发出 GET 请求时导致错误。这使我意识到,对未提交的请求多次调用了我的权限类。这是我的文件。

I have a simple DRF list view and wanted to write some permissions pertaining to POST requests. That resulted in an error when GET requests were issued. That led me to realize that my permission class is being called multiple times on requests that were not submitted. Here are my files.

permissons.py:

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:

views.py:

class UserListView(generics.ListCreateAPIView):
    queryset = User.objects.all()
    serializer_class = UserSerializer
    permission_classes = [IsDummy]

仅当我从浏览器上通过可浏览api提交请求时,才会发生此问题。当我在列表URL上提交GET请求时,我将从 IsDummy 权限类中的print语句向终端打印以下内容:

The issue only happens when I submit a request from my browser on the browsable api. When I submit a GET request at the list url I get the following printed to the terminal from the print statement in the IsDummy permission class:

GET

POST

POST

OPTIONS

当我提交 GET OPTIONS 请求,我看到了我实际使用的单个适当的请求方法。

When I submit a GET or OPTIONS request through postman I see the single, appropriate, request method that I actually used.

似乎列出的第一个方法始终是我曾经不知道额外的 POST OPTION 来自何处。甚至更奇怪的是,即使 POST 请求显然应该导致 IsDummy.has_permission 返回 False

It seems that the first method listed is always the actual method that I used, I have no idea where the extra POSTs and the OPTION are coming from. The even stranger part is that the page will load fine after all of this even though the POST requests should clearly be resulting in IsDummy.has_permission returning a False.

chrome开发工具仅显示一个提交GET 请求,由于它似乎只在可浏览的api中发生,因此我确定它与此有关,但我不知道自己为实现此目的而搞砸了。

The chrome dev tools show only a single GET request being submitted and since it only seems to happen in the browsable api i'm sure it has something to do with that but I can't figure out what I have messed up to make this happen.

推荐答案

浏览器API是一个页面,可以添加\update\删除实例。当您询问此页面时,DRF将检查所有必需的权限,以查看是否允许显示相应的模块。

Browser API is a single page which can add\update\delete instances. When you ask this page, DRF will check all required permission to see if the corresponding module is allowed to display.

深入DRF源代码中,您可以在 renderers.py

Deep in the DRF source code, you can see this in 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对每个实际请求对多个请求类型运行权限检查的原因。

view.check_permissions(request) in show_form_for_method is why DRF browsable API is running permission checks on multiple request types for every actual request.

这篇关于为什么DRF可浏览API针对每个实际请求在多个请求类型上运行权限检查?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆