Django UserPassesTestMixin с параметром

Вот рабочая версия с user_passes_test. Но я хотел бы заменить позицию > 1 на параметр. Я нашел, что это можно сделать с помощью UserPassesTestMixin. Но я не знаю как. Кто-нибудь может помочь?

models.py

class user_control(models.Model):
    user = models.ForeignKey(user, on_delete=CASCADE)    
    position = models.ForeignKey(position, on_delete=CASCADE)
    ...

views.py

def position_check(user):    
    position = 0 if user.is_anonymous else user_control.objects.values(
            'position__rank'
        ).get(
            user = user.id        
        )

    return True if position > 1 else False

@user_passes_test(position_check, login_url='loginPage')
def index(request):
   pass

@user_passes_test(position_check, login_url='loginPage')
def exportReview(request):
   pass

Я пытался:

class PositionCheck(self):    
    position = 0 if user.is_anonymous else user_control.objects.values(
            'position__rank'
        ).get(
            user = self.request.user.id        
        )

    return True if position > (replace with parameter) else False

class Review(PositionCheck, View):
   def index(request):
       pass

   def exportReview(request):
       pass

Вы можете сделать декоратор, который принимает, например, необязательный параметр:

def position_check(function=None, position_value=1, redirect_field_name=REDIRECT_FIELD_NAME, login_url=None):
    def check(user):    
        position = 0 if user.is_anonymous else user_control.objects.values(
            'position__rank'
        ).get(
            user=user.id        
        )
        return position > position_value
    
    actual_decorator = user_passes_test(
        check,
        login_url=login_url,
        redirect_field_name=redirect_field_name,
    )
    if function:
        return actual_decorator(function)
    return actual_decorator

Тогда вы можете использовать декоратор с:

@position_check(position_value=42, login_url='loginPage')
def index(request):
    # …
    pass

Для представления, основанного на классах, использование UserPassesTestMixin миксина [Django-doc] более удобно:

class PositionCheckMixin(UserPassesTestMixin):
    position_value = 1
    
    def test_func(self):
        position = 0 if self.request.user.is_anonymous else user_control.objects.values(
            'position__rank'
        ).get(
            user=self.request.user.id
        )

        return position > self.position_value

тогда вы можете смешать это в представлении на основе класса с:

class MyView(PositionCheckMixin, View):
    position_value = 42
    
    # …
Вернуться на верх