django-allauth login_redirect 页面,用户名为 slug

Posted

技术标签:

【中文标题】django-allauth login_redirect 页面,用户名为 slug【英文标题】:django-allauth login_redirect page with username as slug 【发布时间】:2021-08-16 20:58:47 【问题描述】:

我正在使用 Django 3.2 和 django-allauth 0.44

我在settings.py 中设置了我的LOGIN_REDIRECT_URL,如下所示:

LOGIN_REDIRECT_URL = '个人资料页面'

urls.py,我定义了以下路由:

path('accounts/profile/slug:username', AccountProfileView.as_view(), name='profile-page'),

当我登录时(不出所料),我收到以下错误消息:

NoReverseMatch 在 /accounts/login/ 没有找到没有参数的“profile-page”反向。尝试了 1 种模式:['accounts/profile/(?P[-a-zA-Z0-9_]+)$']

如何将登录用户的用户名参数传递(或指定)给路由?

【问题讨论】:

【参考方案1】:

如果您的视图需要执行不是很简单的重定向,则需要覆盖get_success_url 方法,考虑到您使用django-allauth,您将需要覆盖allauth.account.views.LoginView 并编写自己的url 模式它以便使用您的覆盖视图。首先覆盖视图:

from django.urls import reverse

from allauth.account.views import LoginView as AllauthLoginView
from allauth.account.utils import get_next_redirect_url


class LoginView(AllauthLoginView):
    def form_valid(self, form):
        self.user = form.user # Get the forms user
        return super().form_valid(form)
    
    def get_success_url(self):
        ret = (
            get_next_redirect_url(self.request, self.redirect_field_name)
            or reverse('profile-page', kwargs='username': self.user.username)
        )
        return ret

接下来,无论您在哪里定义 allauth 的 url,只需在其前面添加您自己的 url:

from path_to.view_above import LoginView # Change this import properly


urlpatterns = [
    ...
    path('accounts/login/', LoginView.as_view(), name="account_login"),
    path('accounts/', include('allauth.urls')),
    ...
]

使用 allauth 的另一种替代解决方案是使用自定义 ACCOUNT_ADAPTER 并覆盖它的 get_login_redirect_url,因为如果没有 next 参数,LoginView 将在内部调用它。为此,首先从allauth.account.adapter.DefaultAccountAdapter继承:

from django.urls import reverse

from allauth.account.adapter import DefaultAccountAdapter


class MyAccountAdapter(DefaultAccountAdapter):
    def get_login_redirect_url(self, request):
        return reverse('profile-page', kwargs='username': request.user.username)

settings.py 中的下一步设置ACCOUNT_ADAPTER

ACCOUNT_ADAPTER = "path.to.MyAccountAdapter"

【讨论】:

在进行您建议的更改后,我收到以下错误消息:NoReverseMatch at /accounts/login/ Reverse for 'profile-page' with keyword arguments ''username': '' ' 未找到。尝试了 1 种模式:['accounts/profile/(?P[-a-zA-Z0-9_]+)$'] @HomunculusReticulli 编辑,做检查,还添加了一个最终可能更简单的替代方案。 @AbduAzizBarkat 谢谢!那行得通。您知道为什么您的第一个解决方案不起作用(与 URL 名称不匹配)吗? @HomunculusReticulli 似乎 allauths LoginViewform_valid 方法的工作方式与正常情况有些相反,它首先通过调用 get_success_url然后让用户登录,所以self.request.user.username 不起作用。【参考方案2】:

LOGIN_REDIRECT_URL 应该指向用户在成功登录您的网站后登陆的页面,除非他通过尝试访问任何需要授权的页面而被重定向到登录页面。

如果您想将用户重定向到特定页面(在本例中为他自己的个人资料页面),您可以创建一个中间 URL,该网址将在用户访问时将其重定向到他自己的个人资料页面。可以这样完成:

使用基于类的视图:

class CurrentUserProfileRedirectView(LoginRequiredMixin, RedirectView):

    def get_redirect_url(self, *args, **kwargs):
        return reverse('profile-page', kwargs='username': request.user.username)

或使用基于函数的视图:

@login_required
def current_user_profile(request):
    return redirect('profile-page', username=request.user.username)

接下来,将此重定向视图注册为常规视图,不需要任何参数,并将LOGIN_REDIRECT_URL 设置为此视图的名称。

【讨论】:

以上是关于django-allauth login_redirect 页面,用户名为 slug的主要内容,如果未能解决你的问题,请参考以下文章

django-allauth:将多个社交帐户链接到单个用户

Django Rest Framework + Django-Allauth 密码重置/恢复

无法覆盖 django-allauth 模板

django-allauth 移动客户端 csrf 保护

django-allauth 检索头像头像

Django-allauth Facebook错误