如何正确自定义Django LoginView

时间:2019-02-12 19:38:43

标签: django django-forms django-templates django-views

我正在尝试根据是否是用户当天首次登录来定制django LoginView。我目前已设置我的LoginView,以便它在我的settings.py文件中默认为LOGIN_REDIRECT_URL =“ book:author”。这可以完美地工作。当用户登录并成功通过身份验证后,他们将按照我期望的那样重定向到“ book:author”。

我要尝试的是,如果这是用户当天第一次登录,请将其定向到一个URL,如果是当天的其他登录迭代,请将其重定向到另一个URL。我已经阅读了有关如何执行此操作的各种方法,使用消息传递(而不是使用条件URL重定向到使用NEXT参数)的方法,并且我试图找出哪种方法是解决此问题的最佳,最安全和正确的方法。

这是我的默认LoginView ...(没什么好看的)

template <class T>
vector<T> mergeSort(std::vector<T> lst){
if(lst.size() == 1){
    return lst;
}
else{
    int size = lst.size();
    int low = floor(size/2);
    int high = ceil(size/2);

    vector<T> left(lst[0], lst[low]);
    vector<T> right(lst[low], lst[size]);

    mergeSort(left);
    mergeSort(right);
    merge(lst, left, right);

    return lst;
}


}

template <class T>
vector<T> merge(vector<T>list, vector<T> left, vector<T> right){
auto l = left.begin();
auto r = right.begin();
auto a = list.begin();

while(l != left.end() && r != right.end()){
    if(*r < *l){
        *a = *r;
        r++;
    }
    else{
        *a = *l;
        left++;
    }

    a++;

}

return list;
}

然后根据我的settings.py文件定义进行重定向...

class LoginView(LoginView):
    template_name = 'registration/login.html'
    form_class = AuthenticationForm

将当天的首次登录重定向到其他URL的最佳方法是什么?

预先感谢您的任何建议。

我找到了这样的答案Django -- Conditional Login Redirect,这似乎是我想要的。在底部使用该示例是否有不利之处?

与基于函数的示例相反,如何使用LoginView?

1 个答案:

答案 0 :(得分:1)

为回答您的问题,让我假设您有一个与此模型类似的客户端模型,并且我们需要一个用于存储用户登录信息的助手模型:

models.py:

from django.db import models
from django.contrib.auth.models import User

class Client(models.Model):
    """
    This client model is pointing to django's User model
    You can use your custom user model using AbstractBaseUser or whatever.
    And if you're using django's User model directly, this class is not required
    """
    user = models.OneToOneField(
        User,
        on_delete=models.DO_NOTHING,
        verbose_name='User',
        related_name='cli',  # related name manager if needed
        null=False,
        blank=False,
    )

    def __str__(self):
        return '{}'.format(self.user.username)


class ClientLogins(models.Model):
    """
    This is a helper model table that stores the logins dates of the client
    """
    client = models.ForeignKey(
        Client,
        verbose_name='Client',
        on_delete=models.DO_NOTHING
    )
    date = models.DateTimeField(verbose_name="Date login")

    def __str__(self):
        return '{}'.format(self.client)

然后输入您的表格:

forms.py:

class LoginForm(forms.ModelForm):
    '''Simple login form'''
    class Meta:
        model = User
        fields = ('username', 'password')

最后,应该在视图类/函数中处理您的登录行为。

views.py:

from datetime import timedelta
from django.utils import timezone
from MY_APP import models, forms

class LoginUser(LoginView):
    template_name = 'login.html'  # your template
    from_class = forms.LoginForm  # your form

    def get_success_url(self):
        '''Here the part where you can implement your login logic'''
        now = timezone.now()
        # Get current day date object
        # like: 12/02/2019 00:00:00
        today = now.replace(minute=0).replace(second=0).replace(microsecond=0)
        # Get the client from the user object
        client = self.request.user.cli
        # Get all the user today's logins and count them
        client_logins = models.ClientLogins.objects.filter(
            client=client,
            date__gte=today,
            date__lte=today + timedelta(days=1)
        ).count()
        if client_logins < 1:  # Or: if not client_logins:
            # create a login tracker record
            models.ClientLogins.objects.create(
                client=client,
                date=now  # Store the date where the user logged in the website
            )
            return reverse_lazy('FIRST_LOGIN_REDIRECT_URL')
        # Or redirect to: settings.LOGIN_REDIRECT_URL
        return super().get_success_url()

有关更多信息,这是LoginView的核心代码,像这样,您可以了解MRO列表以及可以覆盖哪些内容以实现所需的行为。