Пользователь проходит тест в django для проверки подписки

У меня есть приложение django, в котором мне нужно проверить, есть ли у пользователя действительная подписка, в противном случае оно перенаправляет пользователя на его/ее приборную панель. Я думал использовать декоратор django user_passes_test, но не смог найти подходящий способ создания функции для проверки пользователя. Мои модели для пользователя и подписки следующие:

class CustomUser(AbstractUser):
    user_type_data = (
    ('admin', 'admin'),
    ('school_admin', 'school_admin'),
    ('student', 'student'),
)
    user_type = models.CharField(
    max_length=20, choices=user_type_data, default='student')
    address = models.CharField(max_length=500, null=True, blank=True)
    city = models.CharField(max_length=200, null=True, blank=True)
    zip_code = models.CharField(max_length=100, null=True, blank=True)
    country = CountryField(null=True, blank=True)
    phone = models.CharField(max_length=200, null=True, blank=True)
    selected_course = models.ForeignKey(QuizTheoryCourse, on_delete=models.CASCADE, null=True, blank=True)

class Subscription(models.Model):
    user = models.OneToOneField(CustomUser, on_delete=models.CASCADE)
    issue_date = models.DateTimeField(null=True, blank=True)
    duration = models.IntegerField(choices=DURATION_CHOICES)
    expiration_date = models.DateTimeField()


def __str__(self):
    return f'{self.user} - {str(self.expiration_date)}'

def get_expiration(self):
    if self.expiration_date:
        if self.expiration_date > timezone.now():
            expiration_date = self.expiration_date + timedelta(days=int(self.duration))
        else:
            expiration_date = dt.now() + timedelta(days=int(self.duration))
    else:
        expiration_date = dt.now() + timedelta(days=int(self.duration))
    return expiration_date


def is_subscription_valid(self):
    today = timezone.now()
    return today < self.expiration_date

Функция, которую я использую для передачи декоратора, следующая:

def subscription_valid(user):
    try:
        superuser = user.is_superuser
        user_valid = user.subscription.is_subscription_valid
        return superuser or user_valid
    except user.DoesNotExist:
        return False

Моя проблема заключается в том, что если у пользователя нет подписки (допустим, он только что зарегистрирован), я получаю ошибку:

CustomUser has no subscription.

Полагаю, что в функции есть что-то вроде оператора if/elif, но я не смог понять, как его обойти.

Ваша идея хороша, но в вашей функции есть некоторые ошибки. Когда вы пытаетесь получить доступ к подписке, Django может поднять исключение ObjectDoesNotExist, а не model.DoesNotExist. Вы можете проверить, существует ли подписка, используя hasattr(user, 'subscription') или попробовать получить доступ и поймать исключение

from django.core.exceptions import ObjectDoesNotExist
def subscription_valid(user):
    try:
        superuser = user.is_superuser
        user_valid = user.subscription.is_subscription_valid
        return superuser or user_valid
    except ObjectDoesNotExist:
        return False

Вернуться на верх