2015-04-15 2 views
4

Я пытаюсь написать пользовательскую функцию rest_framework. Разрешить пользователям запрашивать информацию, не относящуюся к той же компании, что и они. К сожалению, я не могу получить доступ к каким-либо параметрам URL из has_permission() или has_object_permissions().Как я могу получить доступ к параметрам URL из BasePermission?

Вот начало моего маршрутизатора:

# 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) 

Вот мой заказ разрешение:

# 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 

Сейчас проверка 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 

Мне еще предстоит выяснить, как передать эти параметры в разрешение, чтобы он мог выполнить этот дополнительный шаг. Или, может быть, есть лучший способ выполнить то, что я пытаюсь сделать?

ответ

7

Если вы не можете передать их непосредственно (что было бы предпочтительнее), они доступны на объекте запроса:

company_id = request.resolver_match.kwargs.get('company_id') 

request.resolver_match.args и request.resolver_match.kwargs содержат позиционные/ключевое слово аргументы захваченных в вашем URL.

+0

Это сработало отлично! Из любопытства, что бы передать это прямо? Я все еще новичок в DRF, поэтому я даже не знаю, с чего начать, передав его прямо на разрешение. – IAmKale

+0

Я не знаю достаточно о DRF, чтобы помочь вам в этом. – knbk

Смежные вопросы