質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

ただいまの
回答率

87.37%

ログイン前後で、同じURLだが異なる汎用クラスビューを表示したい。

受付中

回答 1

投稿

  • 評価
  • クリップ 0
  • VIEW 822

score 168

実現したいこと
多くのWebサービスではログイン前後でURLが変わりませんがこれはDjangoではどのように実現すれば良いでしょうか。
例 http//:example.com(ログイン画面表示)→ログイン→http://example.com(コンテンツ一覧が表示)

今回の場合、ログイン前は
auth_views.LoginView(ログイン前:http://localhost:8000)→ログイン後→generic.ListView(ログイン後:http://localhost:8000)
にしてコンテンツ一覧を表示したいです。

参考
https://stackoverflow.com/questions/24289095/same-url-in-multiple-views-in-django
https://stackoverflow.com/questions/26571759/one-url-for-two-different-views/26571800
↑によると同じURLに異なるViewを割り当てることはできないようなので、ユーザが認証されたかどうかをifで判断して異なるテンプレートに分けるyうです。上記の回答は関数viewですが汎用ビューの場合にはどう実現すれば良いでしょうか。

urls.py

from django.contrib.auth import views as auth_views
urlpatterns = [
    path('', auth_views.LoginView.as_view(template_name='index.html'), name='index'),

ユーザがログイン後はこのviewを使いたい

from django.views.generic import ListView

class UserIndexView(ListView):
    model = QuizInfo
    template_name = 'user_index.html'


汎用ビューを使わずとももしなにか他にベストプラクティスがありましたら、ご教授お願いします。

環境
Django2.1

  • 気になる質問をクリップする

    クリップした質問は、後からいつでもマイページで確認できます。

    またクリップした質問に回答があった際、通知やメールを受け取ることができます。

    クリップを取り消します

  • 良い質問の評価を上げる

    以下のような質問は評価を上げましょう

    • 質問内容が明確
    • 自分も答えを知りたい
    • 質問者以外のユーザにも役立つ

    評価が高い質問は、TOPページの「注目」タブのフィードに表示されやすくなります。

    質問の評価を上げたことを取り消します

  • 評価を下げられる数の上限に達しました

    評価を下げることができません

    • 1日5回まで評価を下げられます
    • 1日に1ユーザに対して2回まで評価を下げられます

    質問の評価を下げる

    teratailでは下記のような質問を「具体的に困っていることがない質問」、「サイトポリシーに違反する質問」と定義し、推奨していません。

    • プログラミングに関係のない質問
    • やってほしいことだけを記載した丸投げの質問
    • 問題・課題が含まれていない質問
    • 意図的に内容が抹消された質問
    • 過去に投稿した質問と同じ内容の質問
    • 広告と受け取られるような投稿

    評価が下がると、TOPページの「アクティブ」「注目」タブのフィードに表示されにくくなります。

    質問の評価を下げたことを取り消します

    この機能は開放されていません

    評価を下げる条件を満たしてません

    評価を下げる理由を選択してください

    詳細な説明はこちら

    上記に当てはまらず、質問内容が明確になっていない質問には「情報の追加・修正依頼」機能からコメントをしてください。

    質問の評価を下げる機能の利用条件

    この機能を利用するためには、以下の事項を行う必要があります。

質問への追記・修正、ベストアンサー選択の依頼

  • t_obara

    2018/12/05 17:24

    ログイン処理について実装したことはありますか?ベストプラクティスを最初から求めるのではなく、実際に動かして試してみるのが一番だと思います。勉強するには。

    キャンセル

回答 1

0

こちらで執筆されているもののうち、応用セクションのものが参考になると思われます。以下抜粋部です。

TemplateView 、というか ContextMixin の機能として、インスタンス化されたビュークラスを view という名前のテンプレート引数とするため、

urls.py
urlpatterns = [
    url(r'^myapp/a/$', TemplateView.as_view(template_name='myapp/index.html', mode='a'),
        name='myapp-a'),
    url(r'^myapp/b/$', TemplateView.as_view(template_name='myapp/index.html', mode='b'),
        name='myapp-b'),   ...

このような urls にしておき、テンプレートで

myapp/index.html
{% if view.mode == 'a' %}
  モードA表示
{% elif view.mode == 'b' %}
  モードB表示
{% endif %}

このように表示を分岐させることもできます。

ここまでが抜粋部になります。

また、質問者さんがイメージされているところと完全に一致しているかはわかりませんが、多くのログインシステムを持つサイトでは、ログインをするとサイト上部にアカウント名やアカウントメニューが表示されます。この手の表示変更ならば、継承元となるhtmlファイルにnav要素として、以下のような記述で賄うことが可能です。

<nav class="nav bg-light justify-content-end">
    <li class="nav-item justify-content-center">
        <a class="nav-link" href="{% url 'myapp:index' %}">トップページ</a>
    </li>
    {% if user.is_authenticated %}
        <li class="nav-item">
            <a class="nav-link">こんにちは {{ user.get_username }} さん</a>
        </li>
        <li class="nav-item">
            <a class="nav-link" href="{% url 'accounts:logout' %}">ログアウト</a>
        </li>
    {% else %}
        <li class="nav-item">
            <a class="nav-link">こんにちは ゲスト さん</a>
        </li>
        <li class="nav-item">
            <a class="nav-link" href="{% url 'accounts:login' %}">ログイン</a>
        </li>
        <li class="nav-item">
            <a class="nav-link" href="{% url 'accounts:create' %}">アカウント作成</a>
        </li>
    {% endif %}
    {% block nav_item %}{% endblock %}
</nav>

{% if user.is_authentificated %}でユーザーがログインしているかを判定して、ログインしていれば{{ user.get_username }}で名前を取得。ログインしていなければ{% else %}以下の表示が行われて、ログインを促す、といった形です。nav要素やli要素のクラスとして指定されているものはbootstrapを利用したサイト装飾のためのものとなりますので、不要であればもっとシンプルに書くことが可能です。

最後にログイン機能の実装についてですが、ネット上を探してみると、django-allauthやカスタムユーザーモデルを利用したものがよく紹介されています。外部のSNS等と連携したい場合は便利ですが、単なるサンプルサイトで既に初期マイグレーションを実行している場合は上手くいかないと思います。自分の場合は、こちらのサイトを参考にさせて頂いて実装しました。

……と、ここまで書いた上で2018年の質問であることに気づきました。おそらく質問者さんもチェックされていないと思われますが、せっかくなので投稿しておきます。同じような課題を抱えてこちらのサイトに辿り着かれた方の参考になれば幸いです。

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

15分調べてもわからないことは、teratailで質問しよう!

  • ただいまの回答率 87.37%
  • 質問をまとめることで、思考を整理して素早く解決
  • テンプレート機能で、簡単に質問をまとめられる

関連した質問

同じタグがついた質問を見る