naritoブログ

このブログはDjangoとBootstrap4で作成されました
ソースコード

Djangoでログイン画面を自作する

プログラミング関連 Django Python 約449日前
2016年5月25日0:08
デフォルトの/adminではなく、自作でログイン画面をつけます。

インデックス画面


/mypageにアクセスすると、ログインしていない場合は自動でログイン画面に遷移します。


ログインに成功した場合


/loginに直接アクセスし、ログインした場合はredilectへ遷移します



project/project/settings.py


いつもの設定+αです。
INSTALLED_APPS = (
    'django.contrib.admin',
    'django.contrib.auth',
    'django.contrib.contenttypes',
    'django.contrib.sessions',
    'django.contrib.messages',
    'django.contrib.staticfiles',
    'app',
)
...
...
LOGIN_URL = '/login/'  # ログイン画面のURL
LOGIN_REDIRECT_URL = '/redilect/'  # /loginに直接アクセスした場合のリダイレクト


以下の2つの設定がポイントです。
LOGIN_URL = '/login/'  # ログイン画面のURL
LOGIN_REDIRECT_URL = '/redilect/'  # /loginに直接アクセスした場合のリダイレクト


デフォルトでは、以下のような指定がされています。
LOGIN_URL = '/accounts/login/'
LOGIN_REDIRECT_URL = 'accounts/profile/'


もし/adminの管理画面を使いたい、ということならば以下の指定もよいでしょう。
この場合はLOGIN_REDIRECT_URLは不要です。
LOGIN_URL = '/admin/login/'


以下のように、djangoのreverse関数に渡せる形で指定することも可能です。
殆どの場合は、こちらのほうが都合がよいでしょう。
LOGIN_URL = 'app:login'
LOGIN_REDIRECT_URL = 'app:redilect'




project/project/urls.py


from django.conf.urls import include, url
from django.contrib import admin
 
 
urlpatterns = [
    url(r'^admin/', admin.site.urls),
    url(r'^', include('app.urls')),
]



project/app/urls.py


/loginと/logoutは、django.contrib.auth.viewsにあるログイン・ログアウト用の関数ビューを利用します。
(これらの関数ビューはクラスベースビューのLoginView、LogoutViewに置き換わる予定だそうです。クラスベースビューのサンプルは最後にあります。)
template_nameで、使うtemplateも指定しています。

from django.conf.urls import include, url
from django.contrib.auth import views as auth_views
from app import views 

app_name = 'app'

urlpatterns = [
    url(r'^$', views.index, name='index'),
    url(r'^mypage/$', views.mypage, name='mypage'),
    url(r'^redilect/$', views.redilect, name='redilect'),
    url(
        r'^login/$',
        auth_views.login,
        {'template_name': 'app/login.html'},
        name='login'
    ),
    url(
        r'^logout/$',
        auth_views.logout,
        {'template_name': 'app/logout.html'},
        name='logout'
    ),
]



project/app/views.py


関数ビューで作成している例です。
from django.shortcuts import render
from django.contrib.auth.decorators import login_required
 
 
def index(request):
    return render(request, 'app/index.html')
 
 
@login_required
def mypage(request):
    return render(request, 'app/mypage.html')
 
 
@login_required
def redilect(request):
    return render(request, 'app/redilect.html')


このデコレータをつけるだけで、ログインしていない場合はログインページへ飛ばすことができます。
from django.contrib.auth.decorators import login_required
@login_required



project/app/templates/base.html


{% load staticfiles %}
<!DOCTYPE html>
<html lang="ja">
  <head>
    <meta charset="utf-8">
    <title>ログイン画面をつくる</title>
  </head>
  <body>
    {% block content %}
    {% endblock %}
  </body>
</html>



project/app/templates/index.html


{% extends "app/base.html" %}
{% block content %}
インデックスです
{% endblock %}



project/app/templates/mypage.html


{% extends "app/base.html" %}
{% block content %}
ログイン後のマイページ
{% endblock %}



project/app/templates/redilect.html


{% extends "app/base.html" %}
{% block content %}
<p>/loginに直接アクセスした後のリダイレクトページ</p>
{% endblock %}



project/app/templates/logout.html


{% extends 'app/base.html' %}  
{% block content %} 
<p>ログアウトしました</p>
{% endblock %}



project/app/templates/login.html


{% extends 'app/base.html' %} 
{% block content %} 
<form method='post' action='{% url 'app:login' %}'>
{% csrf_token %}
<table>
<tr>
    <td>{{ form.username.label_tag }}</td>
    <td>{{ form.username }}</td>
</tr>
<tr>
    <td>{{ form.password.label_tag }}</td>
    <td>{{ form.password }}</td>
</tr>
</table>
 
<input type='submit' value='login' />
<input type='hidden' name='next' value='{{ next }}' />
</form>
{% endblock %}


Django1.11からは、django.contrib.auth.viewsにあるログイン・ログアウトのクラスベースビューが利用できるようになりました。

urls.py


この例ではurls.pyのみで完結していますが、LoginView、LogoutViewを継承したクラスをviews.pyで定義する、というのも勿論可能です。
from django.conf.urls import include, url
from django.contrib.auth import views as auth_views
from app import views 

app_name = 'app'

urlpatterns = [
    url(r'^$', views.index, name='index'),
    url(r'^mypage/$', views.mypage, name='mypage'),
    url(r'^redilect/$', views.redilect, name='redilect'),
    url(
        r'^login/$',
        auth_views.LoginView.as_view(
            template_name='app/login.html'
        ),
        name='login'
    ),
    url(
        r'^logout/$',
        auth_views.LogoutView.as_view(
            template_name='app/logout.html'
        ),
        name='logout'
    ),
]