Как написать собственные декораторы для модели членства, которые аутентифицируют пользователей на основе их типа членства (представления на основе функций и классов) - PullRequest
0 голосов
/ 27 марта 2019

Я хотел бы настроить пользовательские декораторы, которые будут аутентифицировать пользователей на основе их типов членства

Это для модели django2.Я попытался использовать user_passes_test, который ограничивает доступ неаутентифицированных пользователей, но не предоставляет доступ на основе различных типов членства

models.py

MEMBERSHIP_CHOICES = (
    ('Platinum', 'plt'),
    ('Professional', 'pro'),
    ('Educational', 'edu')
)

class Membership(models.Model):
    slug = models.SlugField()
    membership_type = models.CharField(
            choices=MEMBERSHIP_CHOICES,
            default='edu',
            max_length=30)
    price = models.IntegerField(default=15)
    stripe_plan_id = models.CharField(max_length=40)

    def __str__(self):
        return self.membership_type


class UserMembership(models.Model):
    user = models.OneToOneField(settings.AUTH_USER_MODEL, on_delete=models.CASCADE)
    stripe_customer_id = models.CharField(max_length=40)
    membership = models.ForeignKey(Membership, on_delete=models.SET_NULL, null=True)

    def __str__(self):
        return self.user.username

def post_save_usermembership_create(sender, instance, created, *args, **kwargs):
    if created:
        UserMembership.objects.get_or_create(user=instance)

    user_membership, created = UserMembership.objects.get_or_create(user=instance)

    if user_membership.stripe_customer_id is None or user_membership.stripe_customer_id == '':
        new_customer_id = stripe.Customer.create(email=instance.email)
        user_membership.stripe_customer_id = new_customer_id['id']
        user_membership.save()

post_save.connect(post_save_usermembership_create, sender=settings.AUTH_USER_MODEL)


class Subscription(models.Model):
    user_membership = models.ForeignKey(UserMembership, on_delete=models.CASCADE)
    stripe_subscription_id = models.CharField(max_length=40)
    active = models.BooleanField(default=True)

    def __str__(self):
        return self.user_membership.user.username

    @property
    def get_created_date(self):
        subscription = stripe.Subscription.retrieve(self.stripe_subscription_id)
        return datetime.fromtimestamp(subscription.created)

    @property
    def get_next_billing_date(self):
        subscription = stripe.Subscription.retrieve(self.stripe_subscription_id)
        return datetime.fromtimestamp(subscription.current_period_end)


decorators.py

def professional_membership_required(function=None, redirect_field_name=REDIRECT_FIELD_NAME, login_url='account_login'):


    actual_decorator = user_passes_test(
        lambda u: u.is_active and Membership.membership_type == 'Professional',
        login_url=login_url,
        redirect_field_name=redirect_field_name
    )
    if function:
        return actual_decorator(function)
    return actual_decorator

views.py

@method_decorator([login_required, professional_membership_required], name='dispatch')
class DashboardPage(TemplateView):
    template_name = 'dashboard.html'

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

...