Python 为什么DRF browsable API对每个实际请求的多个请求类型运行权限检查?

Python 为什么DRF browsable API对每个实际请求的多个请求类型运行权限检查?,python,django,django-rest-framework,Python,Django,Django Rest Framework,我有一个简单的DRF列表视图,想写一些关于POST请求的权限。这导致在发出GET请求时出错。这让我意识到,我的权限类在未提交的请求上被多次调用。这是我的档案 permissons.py: 视图。py: 只有当我在可浏览的api上从浏览器提交请求时,才会出现此问题。当我在列表url提交GET请求时,我会从IsDummy权限类中的print语句将以下内容打印到终端: GET POST POST OPTIONS 当我通过邮递员提交GET或OPTIONS请求时,我看到了我实际使用的单一、适当的请

我有一个简单的DRF列表视图,想写一些关于
POST
请求的权限。这导致在发出
GET
请求时出错。这让我意识到,我的权限类在未提交的请求上被多次调用。这是我的档案

permissons.py:

视图。py:

只有当我在可浏览的api上从浏览器提交请求时,才会出现此问题。当我在列表url提交GET请求时,我会从
IsDummy
权限类中的print语句将以下内容打印到终端:

GET

POST

POST

OPTIONS
当我通过邮递员提交
GET
OPTIONS
请求时,我看到了我实际使用的单一、适当的请求方法

似乎列出的第一种方法始终是我使用的实际方法,我不知道额外的
POST
s和
选项
来自哪里。更奇怪的是,尽管
POST
请求显然会导致
IsDummy.has\u permission
返回一个
False
,但在所有这些之后,页面仍将正常加载


chrome开发工具只显示一个提交的
GET
请求,因为它似乎只发生在可浏览的api中,我确信这与此有关,但我不知道是什么让这一切发生的。

浏览器api是一个可以添加\更新\删除实例的单一页面。当您询问此页面时,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\u permissions(request)
in
show\u form\u for\u method
是DRF browsable API对每个实际请求的多个请求类型运行权限检查的原因。

browser API是一个单页,当您请求此页时,它可以添加\更新\删除实例,drf将检查所有必需的权限,以查看相应的模块是否需要displayNice finding:)drf对API请求是否具有相同的行为?不,API请求仅检查请求url所需的权限。谢谢,这正是我要查找的。在权限类中检查方法(例如,
POST
)是否不好?这似乎很奇怪,没有更多的讨论。
GET

POST

POST

OPTIONS
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