繁体   English   中英

Django - 登录后,将用户重定向到他的自定义页面 --> mysite.com/username

[英]Django - after login, redirect user to his custom page --> mysite.com/username

默认情况下,登录后 django 会将用户重定向到帐户/个人资料页面,或者如果您编辑 LOGIN_REDIRECT_URL,您可以将用户发送到您在 settings.py 中指定的另一个页面。

这很好,但我希望用户(登录后)被重定向到一个自定义页面,该页面的链接看起来像这样: mysite.com/username 因此,默认帐户/配置文件或 LOGIN_REDIRECT_URL 设置在这种情况下将不起作用,因为两者都是 static。 在我的例子中,每个用户的地址的username部分都会改变。

有什么想法可以让我在用户登录时将 go 转到在地址中包含用户名的自定义用户页面,例如: mysite.com/username 任何输入都非常感谢。

更简单的方法依赖于页面LOGIN_REDIRECT_URL 的重定向。 要实现的关键是用户信息自动包含在请求中。

假设:

LOGIN_REDIRECT_URL = '/profiles/home'

并且您已经配置了一个 urlpattern:

(r'^profiles/home', home),

然后,您需要为视图home()编写的所有内容是:

from django.http import HttpResponseRedirect
from django.urls import reverse
from django.contrib.auth.decorators import login_required

@login_required
def home(request):
    return HttpResponseRedirect(
               reverse(NAME_OF_PROFILE_VIEW, 
                       args=[request.user.username]))

其中NAME_OF_PROFILE_VIEW是您正在使用的回调的名称。 使用 django-profiles, NAME_OF_PROFILE_VIEW可以是 'profiles_profile_detail'。

您可以按照此处所述对用户进行身份验证和登录: https : //docs.djangoproject.com/en/dev/topics/auth/default/#how-to-log-a-user-in

这将使您能够访问 User 对象,您可以从中获取用户名,然后对自定义 URL 执行 HttpResponseRedirect。

是的! 在您的 settings.py 中定义以下内容

LOGIN_REDIRECT_URL = '/your-path'

并让“/your-path”成为一个简单的视图,它查找self.request.user并执行返回HttpResponseRedirect对象所需的任何逻辑。

更好的方法可能是定义一个简单的 URL,如'/simple' ,它在那里执行查找逻辑。 URL 看起来更漂亮,为您节省一些工作等。

如果您使用的是 Django 的内置LoginView ,则它将next作为上下文,即“成功login后重定向到的 URL。这也可能包含查询字符串。” (见文档

也来自文档:

“如果登录成功,视图会重定向到next指定的 URL。如果没有提供 next,它会重定向到settings.LOGIN_REDIRECT_URL (默认为 /accounts/profile/)。”

示例代码:

urls.py

from django.urls import path
from django.contrib.auth import views as auth_views

from account.forms import LoginForm # optional form to pass to view


urlpatterns = [
    ...

    # --------------- login url/view -------------------
    path('account/login/', auth_views.LoginView.as_view(
        template_name='login.html',  
        authentication_form=LoginForm, 
        extra_context={ 

            # option 1: provide full path
            'next': '/account/my_custom_url/', 

            # option 2: just provide the name of the url
            # 'next': 'custom_url_name',  
        },
    ), name='login'),

    ...
]

login.html

...

<form method="post" action="{% url 'login' %}">

  ...

  {# option 1 #}
  <input type="hidden" name="next" value="{{ next }}">

  {# option 2 #}
  {# <input type="hidden" name="next" value="{% url next %}"> #}

</form>

使用基于类的视图时,另一种选择是使用分派方法。 https://docs.djangoproject.com/en/2.2/ref/class-based-views/base/

示例代码:

设置.py

LOGIN_URL = 'login'
LOGIN_REDIRECT_URL = 'home'

网址.py

from django.urls import path
from django.contrib.auth import views as auth_views
urlpatterns = [
path('', HomeView.as_view(), name='home'),
path('login/', auth_views.LoginView.as_view(),name='login'),
path('logout/', auth_views.LogoutView.as_view(), name='logout'),
]

视图.py

from django.utils.decorators import method_decorator
from django.contrib.auth.decorators import login_required
from django.views.generic import View
from django.shortcuts import redirect

@method_decorator([login_required], name='dispatch')
class HomeView(View):
    model = models.User

    def dispatch(self, request, *args, **kwargs):
        if not request.user.is_authenticated:
            return redirect('login')
        elif some-logic:
            return redirect('some-page') #needs defined as valid url
        return super(HomeView, self).dispatch(request, *args, **kwargs)

最近进入 django 并一直在寻找解决方案并找到一种可能有用的方法。

例如,如果使用 allouth,默认重定向是帐户/配置文件。 使用用户名字段创建一个仅重定向到所选位置的视图,如下所示:

def profile(request):
    name=request.user.username
    return redirect('-----choose where-----' + name + '/')

然后创建一个视图,在您的一个应用程序中捕获它,例如:

def profile(request, name):
    user = get_object_or_404(User, username=name)
    return render(request, 'myproject/user.html', {'profile': user})

urlpatterns 捕获的位置如下所示:

url(r'^(?P<name>.+)/$', views.profile, name='user')

对我来说效果很好。

{% if redirect_field_value == None %}
        <input type="hidden" name="{{ redirect_field_name }}" value="/LOGIN_REDIRECT_URL(instead of typing in settings.py file)/">
      {% else %}
        <input type="hidden" name="{{ redirect_field_name }}" value="{{redirect_field_value}}">
      {% endif %}

我实际上更喜欢@Stu 和其他人提到的方法,即创建一个新的 URL 和一个视图,以便我们可以将重定向逻辑放在那里。 这更容易,用户还可以在浏览器中键入example.com/profile以重定向到他们在example.com/profile/username/上的个人资料。

但是另一种不需要定义额外的 URL 的方法是扩展LoginView并使用配置文件视图的 URL 名称进行重定向。

假设我们有两个名为accountspages的应用程序,并且我们在pages应用程序中定义了个人资料页面,如下所示:

# pages/views.py
from django.views.generic import View
from django.http import HttpResponse

class ProfileView(View):
    def get(self, request, username):
        return HttpResponse('Hello ' + username + '!')

和 URLConf:

# pages/urls.py
from django.urls import path
from .views import ProfileView

app_name = 'pages'
urlpatterns = [
    path('profile/<str:username>/', ProfileView.as_view(), name='profile')
]

请注意,我们必须定义app_name = 'pages'因为我们需要它来引用pages应用程序的 URL。

然后,在accounts应用程序中,我们扩展LoginView并添加重定向逻辑:

# accounts/views.py
from django.contrib.auth.views import LoginView
from django.urls import reverse

class CustomLoginView(LoginView):
    def form_valid(self, form):
        self.success_url_kwargs = {'username': form.cleaned_data['username']}
        return super().form_valid(form)

    def get_success_url(self):
        # 'pages:profile' refers to the 'profile' path in the 'pages' app.
        return reverse('pages:profile', kwargs=self.success_url_kwargs)
# accounts/urls.py
from django.urls import path, include
from .views import CustomLoginView

urlpatterns = [
    path('accounts/login/', CustomLoginView.as_view(), name='login'),
    path('accounts/', include('django.contrib.auth.urls'))
]

成功登录后, form_valid()方法,我们将要在配置文件 URL 中使用的参数添加到自定义 class 属性success_url_kwargs中。 最后,调用return super().form_valid(form)首先将用户登录,然后重定向到get_success_url() (见代码),我们定义它返回我们想要的自定义 URL。

请注意,我们在自定义登录 URL 之后包含了auth应用程序的 URL,以便在我们想要访问accounts/login/时解析第一个。

另外,如果我们需要访问用户 model 实例,我们可以调用form.get_user() 这在某些情况下很有用。 例如,如果用户使用 email 登录并且我们需要他的用户名,我们可以执行form.get_user().username

return render(request,'page_location/page_name')

return render(request,'home/page-login.html')

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM