Пользователь проходит тест в 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