Django:ログイン後に前のページにリダイレクトする


175

私は、SOのログイン機能と非常によく似たログイン機能を備えたシンプルなWebサイトを構築しようとしています。ユーザーは匿名ユーザーとしてサイトを閲覧でき、すべてのページにログインリンクがあります。ログインリンクをクリックすると、ユーザーはログインフォームに移動します。ログインが成功すると、ユーザーは最初にログインリンクをクリックしたページに戻ります。どういうわけか、現在のページのURLをログインフォームを処理するビューに渡す必要があると思いますが、実際には機能しません。

編集:私はそれを理解しました。現在のページをGETパラメータとして渡してログインフォームにリンクし、次に「次へ」を使用してそのページにリダイレクトしました。ありがとう!

編集2:私の説明は明確ではないようだったので、ここにリクエストされたのは私のコードです:foo.htmlのページにいて、ログインしていないとしましょう。今、foo.htmlにリンクしたいのですがlogin.htmlに。そこでログインすると、foo.htmlにリダイレクトされます。foo.htmlのリンクは次のようになります。

      <a href='/login/?next={{ request.path }}'>Login</a> 

ここで、次のようなカスタムログインビューを作成しました。

def login_view(request):
   redirect_to = request.REQUEST.get('next', '')
   if request.method=='POST':
      #create login form...
      if valid login credentials have been entered:
         return HttpResponseRedirect(redirect_to)  
   #...
   return render_to_response('login.html', locals())

そして、login.htmlの重要な行:

<form method="post" action="./?next={{ redirect_to }}">

ええ、それはほとんどそれです、それが明確になることを願っています。


1
Djangoのログイン機能で処理できると思いますが、機能しませんか?
ドミニクロジャー

回答:


151

このために追加のビューを作成する必要はありません。機能はすでに組み込まれています。

最初に、ログインリンクのある各ページで現在のパスを知る必要があります。最も簡単な方法は、リクエストコンテキストプリプロセッサをsettings.py(最初の4つはデフォルトです)に追加することです。次に、リクエストオブジェクトを各リクエストで使用できます。

settings.py:

TEMPLATE_CONTEXT_PROCESSORS = (
    "django.core.context_processors.auth",
    "django.core.context_processors.debug",
    "django.core.context_processors.i18n",
    "django.core.context_processors.media",
    "django.core.context_processors.request",
)

次に、テンプレートにログインリンクを追加します。

base.html:

<a href="{% url django.contrib.auth.views.login %}?next={{request.path}}">Login</a>

これにより、現在のページを指すGET引数がログインページに追加されます。

その場合、ログインテンプレートは次のように簡単になります。

registration / login.html:

{% block content %}
<form method="post" action="">
  {{form.as_p}}
<input type="submit" value="Login">
</form>
{% endblock %}

47
私はこのソリューションを個人的に使用していますが、私が行う1つの変更request.pathは、nullの場合に失敗することです{% firstof request.path '/' %}。そのため、ユーザーが何らかの理由でリクエストパスが利用できない場合に、ユーザーがホームページに送信されるようにします。
jorelli、2011年

1
私はあなたのソリューションを実装しようとしていますが、django.contrib.auth.views.loginがリダイレクトされると(認証に成功した後)、Userのインスタンスはリクエストに含まれないため、user.is_authenticated()は常にFalseを返します。何か助け?
juankysmith 2012年

3
@jorelliに加えて、名前付きURLを使用できます<a href="{% url auth_login %}?next={% firstof request.path '/' %}">Login</a>
hobbes3 2012年

12
また、ユーザーがログアウトした後にログインしたかどうかにも注意する必要があります。言い換えると、これnextはのようなもので/accounts/logout/あり、ユーザーがログインした後、すぐにログアウトされ、笑い、ループが続行します。
hobbes3 2012年

2
これが機能するのは、Django 1.5のログインフォームに<input type = "hidden" name = "next" value = "{{next}}" />
Ellis Percival

28

これは「ベストプラクティス」ではないかもしれませんが、以前はこれをうまく使用しました。

return HttpResponseRedirect(request.META.get('HTTP_REFERER','/'))

10
これには弱点があります-一部のユーザー/ブラウザはリファラーを無効にしています
TomaszZieliński10年

4
ユーザーがフォームに到着し、情報を入力して送信する場合にも問題があります。その場合、HTTP_REFERERはフォームページのURLであり、ユーザーが最初に取得したページのURLではありません。
LaundroMat、2011年

25

必要なparam / valuesで完全なURLをサポートするには:

?next={{ request.get_full_path|urlencode }}

ただの代わりに:

?next={{ request.path }}

実際、これは良い考えではありません。クリック数が多すぎると、クエリ文字列が非常に長くなります
dspjm

14

Djangoの組み込み認証は、思い通りに機能します。

ログインページには、nextログイン後に戻るページであるクエリ文字列が含まれています。

http://docs.djangoproject.com/en/dev/topics/auth/#django.contrib.auth.decorators.login_requiredをご覧ください


4
まあ、login_requiredデコレータは、「next」を私のページに設定するので問題なく機能しますが、デコレータを使用すると、匿名ユーザーはすぐにログインフォームにリダイレクトされるため、サイトを表示できません。ユーザーのアクセス元のページのURLに 'next'の値を設定する方法を理解する必要があるだけだと思います。
–jörg

1

現在のページをGETパラメータとして渡してログインフォームにリンクし、次に「次へ」を使用してそのページにリダイレクトしました。ありがとう!


1

同じ問題が発生しました。このソリューションにより、汎用のログインビューを使い続けることができます。

urlpatterns += patterns('django.views.generic.simple',
    (r'^accounts/profile/$', 'redirect_to', {'url': 'generic_account_url'}),
)

1

registration/login.html(内にネストされたtemplates次の行を挿入した場合、フォルダ)、ページがDjangoの元管理者のログイン・ページのようにレンダリングされます:

{% include "admin/login.html" %}

注:ファイルには上記の行のみを含める必要があります。


-1

views.login()についてはdjango docsを参照してください。ログインが成功した後にリダイレクトするために、入力フォームに「非表示フィールド」として「次の」値を指定します。


はい、でも実際にどのようにして「次」を自分のページに設定しますか?
イェルク・

-3

これもできます

<input type="hidden" name="text" value="{% url 'dashboard' %}" />

間違った答えですが、name = 'next'は実行可能であり、テストされていません。
WeizhongTu 2016
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.