如何正确自定义 Django LoginView

2024-05-15

我试图弄清楚如何根据用户当天是否第一次登录来自定义 django LoginView。我当前已设置 LoginView,使其默认为 settings.py 文件中的 LOGIN_REDIRECT_URL = "book:author" 。这工作完美无缺。当用户登录并成功通过身份验证时,他们将被重定向到“book:author”,正如我所期望的那样。

我想做的是,如果这是用户当天第一次登录,则将他们定向到一个 URL,如果是当天的任何其他登录迭代,则将他们重定向到另一个 URL。我已经阅读了有关如何执行此操作的各种方法,使用消息传递而不是条件 URL 重定向来使用 NEXT 参数,并且我试图找出哪种方法是最好、最安全和正确的方法。

这是我的默认登录视图...(没什么花哨的)

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

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

    LOGIN_REDIRECT_URL = "book:author" 

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

在此先感谢您的任何建议。

我找到了这个答案Django——条件登录重定向 https://stackoverflow.com/questions/16824004/django-conditional-login-redirect这似乎就是我正在寻找的。使用底部的示例有什么缺点吗?

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


为了回答你的问题,让我假设你有一个客户端模型,在某种程度上,类似于这个模型,我们需要一个存储用户登录信息的辅助模型:

模型.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)

然后你的表格:

形式.py:

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

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

视图.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 https://github.com/django/django/blob/master/django/contrib/auth/views.py#L38,这样你就可以知道MRO列出以及您可以覆盖哪些内容以获得您想要的行为。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

如何正确自定义 Django LoginView 的相关文章

随机推荐