2017-01-25 4 views
0

Я пытаюсь настроить разные классы разрешений, но, на мой взгляд, коды на 95% одинаковы. Если есть возможный способ, я действительно хочу сделать так, чтобы их можно было легко комбинировать и легко называть.Как объединить сходные классы или включить их в функцию?

Скажем, у меня есть два различных пользовательских разрешений

class IsUser1(BasePermission): 
    def has_permission(self, request, view): 
     if not request.user.is_anonymous: 
      try: 
       request.user.user1 
       return True 
      except Exception: 
       return False 
     return False 

    def has_object_permission(self, request, view, obj): 
     pass 


class IsUser2(BasePermission): 
    def has_permission(self, request, view): 
     if not request.user.is_anonymous: 
      try: 
       request.user.user2 
       return True 
      except Exception: 
       return False 
     return False 

    def has_object_permission(self, request, view, obj): 
     pass 

Есть простой и возможный путь для этого?

+0

Что есть в запросе? Вы просто пытаетесь выяснить, что это за пользователь? можете ли вы показать использование этих классов в контексте? – depperm

+0

Объединить их в каком смысле? Какова ваша цель? – martineau

ответ

1

Не имея лучшего понимания того, что вы пытаетесь сделать, это похоже на возможный способ реорганизации кода для устранения дублирования кода.

Он работает на том основании, что только различие между реализациями has_permission для IsUser1 и IsUser2 является в user собственности они пытаются получить доступ, поэтому я определить общий супертип каждого класса, который принимает обратный вызов от каждого, который определяет, какую недвижимость он пытается получить доступ к полученным запросам.

from abc import abstractmethod 


class BasePermission(object): 
    @abstractmethod 
    def has_permission(self, request, view): 
     pass 


class BaseUserPermission(BasePermission): 
    def __init__(self, user_selector): 
     self.user_selector = user_selector 

    def has_permission(self, request, view): 
     if not request.user.is_anonymous: 
      try: 
       self.user_selector(request) 
       return True 
      except Exception: 
       return False 
     return False 

    def has_object_permission(self, request, view, obj): 
     pass 


class IsUser1(BaseUserPermission): 
    def __init__(self): 
     super().__init__(lambda request: request.user.user1) 


class IsUser2(BaseUserPermission): 
    def __init__(self): 
     super().__init__(lambda request: request.user.user2) 
+0

Возможно, стоит упомянуть, что строка 'class BasePermission (object):' имеет значение для старого кода Python 2, чтобы создать новый класс стиля. В Python 3 'class BasePermission:' достаточно. – cdarke

+0

@cdarke Это правда. Даже если это не нужно, я думаю, что это лучший стиль. «Явный лучше, чем неявный». - Дзен Питона. – Tagc

+0

@Tagc thx! это превосходно, но я немного смущен, как эта часть работает? 'self.user_selector (request)' как это проходит в '(лямбда-запрос: request.user.user2)' – Dora