如何从BasePermission中访问URL参数?

IAm*_*ale 7 django django-rest-framework

我正在尝试编写自定义的rest_framework权限,以防止用户查询与他们不属于同一公司的信息.不幸的是,我似乎无法访问任何URL的参数从内部has_permission()has_object_permissions().

这是我的路由器的开头:

# Create a basic router
router = routers.SimpleRouter()
# Establish some variables to assist with nested routes
root_elem = 'companies'
root_elem_id = '/(?P<company_id>[0-9]+)'
loca_elem = '/locations'
loca_elem_id = '/(?P<location_id>[0-9]+)'
# Companies will be the root from which all other relations branch
router.register(r'' + root_elem, views.CompanyViewSet)
router.register(r'' + root_elem + root_elem_id + loca_elem,
                views.LocationViewSet)
Run Code Online (Sandbox Code Playgroud)

这是我的自定义权限:

# Only permit actions originating from location managers or company admins
class IsLocationManagerOrHigher(BasePermission):
    # Checked when displaying lists of records
    def has_permission(self, request, *args, **kwargs):
        is_correct_level = False
        # Admins can see every location if their location_id
        # matches a location that's a child of the company
        # specified in the URL
        if request.employee.is_admin:
            is_correct_level = True

        return request.user and is_correct_level

    # Checked when viewing specific records
    def has_object_permission(self, request, view, obj):
        is_correct_level = False
        # Admins can see location details if their location's company_id
        # matches a Location's company_id
        if request.employee.is_admin:
            is_correct_level = True
        # Managers can see location details if it's their location
        elif obj.id == request.employee.location_id and request.employee.is_manager:
            is_correct_level = True

        return request.user and is_correct_level
Run Code Online (Sandbox Code Playgroud)

现在检查request.employee.is_admin只是我需要的一半 - 我还需要company_id从URL 访问并确保它与管理员的位置匹配company_id:

# Pseudocode
try:
    user_location = Location.objects.get(id=request.employee.location_id)
    return user_location.company_id == kwargs['company_id']
except ObjectDoesNotExist:
    pass
Run Code Online (Sandbox Code Playgroud)

我还没弄清楚如何将这些参数传递给Permission,以便它可以执行这个额外的步骤.或者也许有更好的方法来完成我想要做的事情?

knb*_*nbk 12

如果你不能直接传递它们(这是更好的),它们在请求对象上可用:

company_id = request.resolver_match.kwargs.get('company_id')
Run Code Online (Sandbox Code Playgroud)

request.resolver_match.argsrequest.resolver_match.kwargs包含您网址中捕获的位置/关键字参数.


Roc*_*ckk 7

作为 knbk 发布的正确响应的替代方法,您还可以使用传递给has_permission方法的视图对象获取 URL 参数。像这样:

company_id = view.kwargs.get('company_id')