如何正确自定义Django LoginView [英] How To Properly Customize Django LoginView

查看:458
本文介绍了如何正确自定义Django LoginView的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I am trying to figure out how to customize the django LoginView based on whether or not it's the user's first time logging on for the day. I have my LoginView currently set up so that it defaults to the LOGIN_REDIRECT_URL = "book:author" in my settings.py file. This works flawlessly. When a user logins in and is successfully authenticated, they are redirected to "book:author" as I would expect.

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

What I'm trying to do is if this is the first time the user has logged in for the day, direct them to one URL, and if it's any other login iteration for the day, redirect them to a different URL. I have read about various methods on how to do this, to use messaging as opposed to conditional URL redirect to using the NEXT parameter and I'm trying to figure out which is the best and most secure and proper way of going about this.

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

Here is my default LoginView...( Nothing fancy )

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

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

And then it redirects based on my settings.py file definition...

    LOGIN_REDIRECT_URL = "book:author" 

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

What is the best way to redirect for first login of the day to different URL?

在此先感谢任何建议。

我找到了这个答案 Django-条件登录重定向,这似乎是我想要的。在底部使用示例是否有不利之处?

I found this SO answer Django -- Conditional Login Redirect and it seems to be what I'm looking for. Are there any downsides to using the example at the bottom?

以及如何使用LoginView而不是基于函数的示例?

And how to do with a LoginView as opposed to the function based example?

推荐答案

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

To answer your question, let me suppose you have a client model, in a way, similar to this model, and we'll need a helper models that stores the user's logins:

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')

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

And finally, your login behaviour should be treated in the views classes/functions.

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 列表,以及可以覆盖哪些内容以实现所需的行为。

And for more informations, this is the core code of LoginView, like this you can know the MRO list and what you can override to have your desired behaviour.

这篇关于如何正确自定义Django LoginView的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆