簡體   English   中英

為什么DRF可瀏覽API針對每個實際請求在多個請求類型上運行權限檢查?

[英]Why is DRF browsable API running permission checks on multiple request types for every actual request?

我有一個簡單的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

當我通過郵遞員提交GETOPTIONS請求時,我看到了我實際使用的單個適當的請求方法。

似乎列出的第一個方法始終是我使用的實際方法,我不知道多余的POSTOPTION來自何處。 甚至更奇怪的部分是,即使POST請求明顯導致IsDummy.has_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_permissions(request)show_form_for_method就是為什么DRF可瀏覽API運行在多個請求類型的權限檢查每一個實際的請求。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM