Djangoでログイン機能を作る
今回はDjangoにもともと用意されている機能だけでログイン機能(ユーザー認証)を実装してみようと思います。
環境
python 3.6.3 Django 2.0.8
プロジェクトの作成
まずは、Djangoのプロジェクトを作るところから始めましょう。myproject
という名前のプロジェクトを作成します。
適当なディレクトリに移動して
django-admin.py startproject myproject
これで以下のような構成のファイル群が出来上がります。
./myproject
├── manage.py
└── myproject
├── __init__.py
├── settings.py
├── urls.py
└── wsgi.py
アプリケーションの作成
続いてログイン機能用にアプリケーションaccounts
を作成します。myproject
のディレクトリに移動します。
移動したディレクトリで
python manage.py startapp accounts
これを実行すると
accounts
├── __init__.py
├── admin.py
├── apps.py
├── migrations
│ └── __init__.py
├── models.py
├── tests.py
└── views.py
が出来上がります。
ここまで出来たらaccounts
の中にurls.py
とforms.py
を足しましょう。
中身は後述します。
accounts
├── __init__.py
├── admin.py
├── apps.py
├── forms.py
├── migrations
│ └── __init__.py
├── models.py
├── tests.py
├── urls.py
└── views.py
こんな感じになっていれば正解です。
一度./myproject
に戻ります。./myproject/myproject/settings.py
のINSTALLED_APPSに以下のように追記します。
INSTALLED_APPS = [
'django.contrib.admin',
'django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.sessions',
'django.contrib.messages',
'django.contrib.staticfiles',
'accounts.apps.AccountsConfig', # 追記
]
./myproject/myproject/urls.py
にも以下のように追記します。
from django.contrib import admin
from django.urls import path,include # include を追記
urlpatterns = [
path('admin/', admin.site.urls),
path('accounts/',include('accounts.urls')), # 追記
]
ここまで出来たら次のコマンドを実行します。
python manage.py makemigrations
出力
No changes detected
python manage.py migrate
出力
Operations to perform:
Apply all migrations: admin, auth, contenttypes, sessions
Running migrations:
Applying contenttypes.0001_initial... OK
Applying auth.0001_initial... OK
Applying admin.0001_initial... OK
Applying admin.0002_logentry_remove_auto_add... OK
Applying contenttypes.0002_remove_content_type_name... OK
Applying auth.0002_alter_permission_name_max_length... OK
Applying auth.0003_alter_user_email_max_length... OK
Applying auth.0004_alter_user_username_opts... OK
Applying auth.0005_alter_user_last_login_null... OK
Applying auth.0006_require_contenttypes_0002... OK
Applying auth.0007_alter_validators_add_error_messages... OK
Applying auth.0008_alter_user_username_max_length... OK
Applying auth.0009_alter_user_last_name_max_length... OK
Applying sessions.0001_initial... OK
次はいよいよログイン機能を作っていこうと思います。
ログイン機能を作る
ログインページの準備
Djangoの標準のログインページを利用してもよいのですが、大体の人はカスタマイズしたいと思うので、ログインページを自作していきましょう。/myproject/accounts/templates/accounts
にlogin.html
とlogout.html
を作ります。
それに加えてログインが成功したとき用のindex.html
を作成します。
それぞれの中身は以下の通りです。
login.html
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<title>LOGIN</title>
<meta name="viewport" content="width=device-width, initial-scale=1">
</head>
<body>
<form action="" method="POST">
{% csrf_token %}
{{ form.as_p }}
<button type="submit">ログイン</button>
</form>
</body>
</html>
logout.html
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<title>LOGOUT</title>
<meta name="viewport" content="width=device-width, initial-scale=1">
</head>
<body>
<form action="" method="POST">
{% csrf_token %}
<button type="submit">ログアウト</button>
</form>
</body>
</html>
index.html
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<title>index</title>
<meta name="viewport" content="width=device-width, initial-scale=1">
</head>
<body>
<p>トップページ</p>
<a href="{% url 'logout' %}">ログアウト</a>
</body>
</html>
forms.pyの準備
./myproject/accounts/forms.py
の中身は以下のような感じ
from django.contrib.auth import forms as auth_forms
class LoginForm(auth_forms.AuthenticationForm):
'''ログインフォーム'''
def __init__(self, *args, **kw):
super().__init__(*args, **kw)
for field in self.fields.values():
field.widget.attrs['placeholder'] = field.label
views.pyの準備
./myproject/accounts/views.py
の中身は以下のような感じ
from django.contrib.auth.views import LoginView, LogoutView
from django.contrib.auth.mixins import LoginRequiredMixin
from django.views.generic import TemplateView
from . import forms
class MyLoginView(LoginView):
form_class = forms.LoginForm
template_name = "accounts/login.html"
class MyLogoutView(LoginRequiredMixin, LogoutView):
template_name = "accounts/logout.html"
class IndexView(TemplateView):
template_name = "accounts/index.html"
urls.pyの準備
./myproject/accounts/urls.py
の中身は以下のような感じ
from django.urls import path
from . import views
urlpatterns = [
path('login/', views.MyLoginView.as_view(), name="login"),
path('logout/', views.MyLogoutView.as_view(), name="logout"),
path('index/',views.IndexView.as_view(), name="index")
]
settings.pyの準備
./myproject/myproject/settings.py
の最後に以下を追記します。
LOGIN_URL = 'login' # ログインしていないときのリダイレクト先
LOGIN_REDIRECT_URL = 'index' # ログイン後のリダイレクト先
LOGOUT_REDIRECT_URL = 'index' # ログアウト後のリダイレクト先
ここまで出来たら
python manage.py createsuperuser
でアカウントを作成しましょう。
python manage.py runserver
でサーバーを起動してhttp://localhost:8000/accounts/login/
にアクセスして先ほど作成したアカウントでログインできるか確認しましょう。
ログインができれば成功です。
ユーザーの新規作成ページ
続いてwebページ上でアカウントの作成ができるように改造していきましょう。
template/accounts/create.html
を新たに作成
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<title>CREATE</title>
<meta name="viewport" content="width=device-width, initial-scale=1">
</head>
<body>
<p>新規ユーザーの作成</p>
<form action="" method="POST">
{% csrf_token %}
{{ form.as_p }}
<button type="submit">作成</button>
</form>
</body>
</html>
./myproject/accounts/views.py
に追記
from django.contrib.auth.views import LoginView, LogoutView
from django.contrib.auth.mixins import LoginRequiredMixin
from django.views.generic import TemplateView,CreateView # 追記
from django.contrib.auth.forms import UserCreationForm # 追記
from django.urls import reverse_lazy # 追記
from . import forms
class MyLoginView(LoginView):
form_class = forms.LoginForm
template_name = "accounts/login.html"
class MyLogoutView(LoginRequiredMixin, LogoutView):
template_name = "accounts/logout.html"
class IndexView(TemplateView):
template_name = "accounts/index.html"
# 追記
class UserCreateView(CreateView):
form_class = UserCreationForm
template_name = "accounts/create.html"
success_url = reverse_lazy("login")
./myproject/accounts/urls.py
にも追記
from django.urls import path
from . import views
urlpatterns = [
path('login/', views.MyLoginView.as_view(), name="login"),
path('logout/', views.MyLogoutView.as_view(), name="logout"),
path('index/', views.IndexView.as_view(), name="index"),
path('create/', views.UserCreateView.as_view(),name="create"), # 追記
]
これでサーバーを起動してhttp://localhost:8000/accounts/create/
にアクセスすればユーザーの新規作成画面が表示されるはずです。
表示出来たらユーザーを作ってみましょう。
ユーザーを作成したらログインができるかも確認してみましょう。