处理Django用户订阅的到期日期

时间:2018-07-05 10:01:06

标签: django authentication

我有一个扩展AbstractBaseUser的用户模型

class User(AbstractBaseUser):
    email = models.EmailField(max_length=255, unique=True, default='abc123@gmail.com')
    forename = models.CharField(max_length=20, default='')
    surname = models.CharField(max_length=20, default='')
    account_expiry = models.DateField(default=datetime.now() + timedelta(days=365))

在我所有的视图中,我都使用LoginRequiredMixin进行身份验证

class IndexView(LoginRequiredMixin, generic.TemplateView):

我不仅要通过电子邮件和密码对用户进行身份验证,还要通过检查帐户的有效期限是否到来来进行验证。

我的问题是-实现这一目标的最佳(最简单)方法是什么?我是否编写自己的自定义身份验证后端as described here?还是应该编写自定义的Mixin或中间件?

2 个答案:

答案 0 :(得分:0)

您可以重新实现is_authenticated的{​​{1}}属性,以在帐户过期后返回AbstractBaseUser

为防止过期的用户登录,您还可以覆盖False以在帐户过期时返回False。

答案 1 :(得分:0)

所以最终我的解决方案是创建自己的自定义中间件。

我发现How to Create a Custom Django Middleware是一个有用的起点,但是它对我不起作用,因为我使用的是Django 2.0.1。 The official docs解释了如何更新解决方案,我还发现this SO的帖子很有用。

所以我的代码如下:

class AccountExpiry:

def __init__(self, get_response):
    self.get_response = get_response

def __call__(self, request):
    current_user = request.user
    response = self.get_response(request)
    expiry_path = reverse('accounts:account-expired')

    if current_user.is_anonymous is False:
        if current_user.admin is False and current_user.staff is False:
            if request.path not in [expiry_path]:
                expiry_date = current_user.school.account_expiry
                todays_date = datetime.today().date()

                if todays_date > expiry_date:
                    return HttpResponseRedirect(expiry_path)
    return response

(请注意,account_expiry实际上是相关表(学校)中的一个字段,而不是按照我上面的原始问题在用户模型中的字段)。

我将设置MIDDLEWARE =更新为包括

'common.middleware.AccountExpiry',

它可以按我的意愿工作。