--- title: DJango1.10 ログイン チュートリアル tags: #django author: kitamuratomokazu slide: false --- ###準備 pyenv等の隔離環境でdjangoのinstallを推奨します。 django1.10を対象に記載します。 ``` $pip install django ``` ####プロジェクトの作成 default_loginという名称でプロジェクトを作成します。 ``` $mkdir django_login $cd django_login $django-admin.py startproject default_login $cd default_login $python manage.py migrate $python manage.py createsuperuser (superuser作成) $python manage.py runserver ``` http://127.0.0.1:8000/admin で管理画面にログインしてみます。 作成したユーザーとパスワードを利用します。 ####アプリケーションの作成 accountsという名称でアプリケーションを作成します。 ``` $python manage.py startapp accounts $ls -a (フォルダが作成されたか確認) ``` settings.pyに accounts を追加します。 ついでに日本語とタイムゾーンの設定も追加します。 ```django_login/default_login/default_login/settings.py INSTALLED_APPS = ( : 'accounts', ) LANGUAGE_CODE = 'ja' TIME_ZONE = 'Asia/Tokyo' ``` ###URL Djangoは標準でログインやログアウトのビューを用意してくれています。 url.pyでデフォルトのログインビューを利用してurlディスパッチを行います。 ```django_login/default_login/default_login/urls.py from django.conf.urls import include, url from django.contrib import admin urlpatterns = [ url(r'^admin/', include(admin.site.urls)), url('^', include('django.contrib.auth.urls')), ] ``` 注意:Django1.10からログインビューにつきましてはurl(r'^accounts/login/$','django.contrib.auth.views.login')からurl('^',include('django.contrib.auth.urls'))へ変更されています。 urls.pyにinclude('django.contrib.auth.urls') を記述することで、認証関連のURLとそれに対応するビューが追加されます。 詳細は、django.contrib.auth.urlsの中に記載されています。 以下はdjango.contrib.auth.urlsの中身です。「password_change」等からわかるように、パスワード変更用のURLおよびビューが標準で提供されています。 (*今回は時間の制約上、ログインとログアウトのみの実装にとどめます。) > https://docs.djangoproject.com/en/1.10/topics/auth/default/#module-django.contrib.auth.views ^login/$ [name='login'] ^logout/$ [name='logout'] ^password_change/$ [name='password_change'] ^password_change/done/$ [name='password_change_done'] ^password_reset/$ [name='password_reset'] ^password_reset/done/$ [name='password_reset_done'] ^reset/(?P[0-9A-Za-z_\-]+)/(?P[0-9A-Za-z]{1,13}-[0-9A-Za-z]{1,20})/$ [name='password_reset_confirm'] ^reset/done/$ [name='password_reset_complete'] ####Templateの作成 accountsの直下にtemplatesフォルダを生成します。 ``` $cd accounts $mkdir templates ``` templates直下にbase.htmlを作成します。 以下を記述します。 ```django_login/default_login/accounts/templates/base.html Welcome Kobe Python MeetUp! {% block content %} {% endblock %} ``` defaultのログインビューを利用するためにtemplatesの下にregistrationフォルダを作成します。 registrationフォルダの下にlogin.htmlを作成します。 (注意:このディレクトリ構成と名前が必要です。) ``` mkdir registration ``` ```django_login/default_login/accounts/templates/registration/login.html {% extends "base.html" %} {% block content %} ai {% if form.errors %}

Your username and password didn't match. Please try again.

{% endif %}
{% csrf_token %}
{{ form.username.label_tag }} {{ form.username }}
{{ form.password.label_tag }} {{ form.password }}
{# Assumes you setup the password_reset view in your URLconf #}

Lost password?

{% endblock %} ``` この時点でログインURLにアクセスしてログインしても何もおきません。(下記参照) http://127.0.0.1:8000/login ※ログイン用のユーザIDとパスワードはsuperuser作成時の管理者アカウントを使います。 > If called via POST with user submitted credentials, it tries to log the user in. If login is successful, the view redirects to the URL specified in next. If next isn’t provided, it redirects to settings.LOGIN_REDIRECT_URL (which defaults to /accounts/profile/). If login isn’t successful, it redisplays the login form. ログインに成功するとhelloビューが呼ばれ、hello.htmlが表示されるようにします。 ログインした後のURLをsettings.pyに記載しビュー、テンプレートを次のように用意します。 ```django_login/default_login/default_login/settings.py # 追記 LOGIN_REDIRECT_URL = '/accounts/hello/' LOGIN_URL = '/login' ``` accountsで始まるurlはaccouts/urlに飛ばすように下記追記します。 ```django_login/default_login/default_login/urls.py from django.conf.urls import include, url from django.contrib import admin urlpatterns = [ url(r'^admin/', include(admin.site.urls)), url('^', include('django.contrib.auth.urls')), url(r'^accounts/', include('accounts.urls',namespace='accounts')), ] ``` accouts以下でのurlの処理です。 accounts/helloとrequestがきた際にhelloビューが呼ばれるように設定します。 accountsフォルダの中にurls.pyを作成し以下を記載します。 ```django_login/default_login/accounts/urls.py from django.conf.urls import url from . import views urlpatterns = [ url(r'hello/$', views.hello, name='hello'), ] ``` hello.htmlを作成します。 ```django_login/default_login/accounts/templates/hello.html {% extends "base.html" %} {% block content %}

Log out

Hello! {{ name }}

{% endblock %} ``` ###ビューの作成 helloのビューを作成します。 ```django_login/default_login/accounts/views.py from django.shortcuts import render # Create your views here. def hello(request): name = request.user print(name) return render(request, 'hello.html', {'name': name}) ``` これでログインに成功するとhello.htmlが表示され自分の名前が表示されるはずです。 python manage.py runserverを実行します。 ###閲覧制限の追加 helloビューはログインしたユーザーにのみ閲覧可能にしていきます。 helloビューにlogin_requiredデコレーターを追加するだけでOKです。 ```django_login/default_login/accounts/views.py from django.shortcuts import render from django.contrib.auth.decorators import login_required # Create your views here. @login_required(login_url='/login/') def hello(request): name = request.user print(name) return render(request, 'hello.html', {'name': name}) ``` ログインしていない状態でhttp://127.0.0.1:8000/accounts/hello にアクセスするとloginページに遷移するようになります。 さらに認証を名前からEmailにかえてみます。 ```django_login/default_login/default_login/backends.py  from django.contrib.auth.hashers import check_password from django.contrib.auth import get_user_model from django.contrib.auth.backends import ModelBackend class UserModelEmailBackend(ModelBackend): def authenticate(self, username="", password="", **kwargs): try: user = get_user_model().objects.get(email__iexact=username) if check_password(password, user.password): return user else: return None except get_user_model().DoesNotExist: # No user was found, return None - triggers default login failed return None ``` settings.pyに AUTHENTICATION_BACKENDS = [ 'default_login.backends.UserModelEmailBackend', # Login w/ email ] を追記します。 これで、とりあえずEmailで認証することができるはずです。