【Django】簡単なSNSアプリを開発する④~ログイン機能実装~
スポンサードリンク
おはようございます。Shotaです。
今回も、前回と同様にDjangoで簡単なSNSアプリを開発するための方法を解説していきます。
今回はログイン機能を実装していきます。
▼前回の記事はコチラ
shotanukumizu-1000.hatenablog.com
▼初回の記事はコチラ
shotanukumizu-1000.hatenablog.com
HTMLテンプレートの作成
基本設定(Django側)
まずは、_project/settings.py
にアクセスして以下のコードを書いてください。
#_project/settings.py #...(中略)... STATIC_URL = '/static/' STATIC_ROOT = BASE_DIR / 'staticfiles' STATICFILES_DIRS = [str(BASE_DIR / 'static')]
定数STATIC_ROOT
やSTATICFILES_DIRS
を新しく設定することで、Django側にcssファイルやjsファイルのようなstatic
ファイルを新しく読み込ませられるようになります。
次に、_project/urls.py
にアクセスして以下のコードを書いてください。
#_project/urls.py from django.contrib import admin from django.urls import path, include from django.conf.urls.static import static from django.conf import settings urlpatterns = [ path('admin/', admin.site.urls), path('mdeditor/', include('mdeditor.urls')), path('', include('_app.urls')), ] if settings.DEBUG: urlpatterns += static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT) \ + static(settings.STATIC_URL, document_root=settings.STATIC_ROOT) #追加
このように設定することで、Django側でstatic
ファイルを読み込ませられるようになりました。
static
ファイルの読み込み
_project
フォルダと同じ場所にstatic
ファイルを作成してください。そして、loginform.css
を新規で作成して以下のコードを書いてください。
html, body { height: 100%; } body { display: flex; align-items: center; padding-top: 40px; padding-bottom: 40px; background-color: #f5f5f5; } .form-signin { width: 100%; max-width: 330px; padding: 15px; margin: auto; } .form-signin .checkbox { font-weight: 400; } .form-signin .form-control { position: relative; box-sizing: border-box; height: auto; padding: 10px; font-size: 16px; } .form-signin .form-control:focus { z-index: 2; } .form-signin input[type="email"] { margin-bottom: -1px; border-bottom-right-radius: 0; border-bottom-left-radius: 0; } .form-signin input[type="password"] { margin-bottom: 10px; border-top-left-radius: 0; border-top-right-radius: 0; }
これでstatic
ファイルの用意は完成です。
HTMLファイルの作成
template
フォルダに移動して、それぞれ新しくsignup.html
とlogin.html
を作成してください。今回はBootstrapで多少楽をしていこうと思います。
<!----templates/signup.html----> {% extends 'base.html' %} {% load static %} {% block customcss %} <link rel="stylesheet" href="{% static 'loginform.css' %}"> {% endblock customcss %} {% block title %} <title>Sign Up</title> {% endblock title %} {% block content %} <body class="text-center"> {{ error }} <div class="container"> <form class="form-signin" method="POST">{% csrf_token %} <h1 class="h3 mb-3 fw-normal">サインインする</h1> <label for="inputEmail" class="visually-hidden">メールアドレス</label> <input type="text" id="inputEmail" class="form-control" placeholder="ユーザ名" name="username" required autofocus> <label for="inputPassword" class="visually-hidden">パスワード</label> <input type="password" id="inputPassword" class="form-control" placeholder="パスワード" name="password" required> <button class="w-100 btn btn-lg btn-primary" type="submit">サインイン</button> <p class="mt-5 mb-3 text-muted">© 2017-2021</p> </form> </div> </body> {% endblock content %}
<!---templates/login.html-----> {% extends 'base.html' %} {% load static %} {% block customcss %} <link rel="stylesheet" href="{% static 'loginform.css' %}"> {% endblock customcss %} {% block title %} <title>Login</title> {% endblock title %} {% block content %} <body class="text-center"> <div class="container"> <form class="form-signin" method="POST">{% csrf_token %} <h1 class="h3 mb-3 fw-normal">ログインする</h1> <label for="inputEmail" class="visually-hidden">メールアドレス</label> <input type="text" id="inputEmail" class="form-control" placeholder="ユーザ名" name="username" required autofocus> <label for="inputPassword" class="visually-hidden">パスワード</label> <input type="password" id="inputPassword" class="form-control" placeholder="パスワード" name="password" required> <button class="w-100 btn btn-lg btn-primary" type="submit">ログイン</button> <p class="mt-5 mb-3 text-muted">© 2017-2021</p> </form> </div> </body> {% endblock content %}
<!---templates/index.html(ログイン完了後のページ)-----> {% extends 'base.html' %} {% block title %} <title>投稿内容</title> {% endblock title %} {% block content %} <h1>This is an Index Page.</h1> <a href="{% url 'logout' %}">ログアウト</a> {% endblock content %}
あと、セキュリティ上のエラーを防ぐためDjangoで入力画面等のフォームを実装する際はform
属性の最初に{% csrf_token %}
を絶対つけるようにしてください。
これでログインページとアカウント登録ページは完成です。
登録(signup
)
次に、Django側でログイン機能の実装をやっていきます。_app/views.py
にアクセスして、以下のコードを書いてください。
#_app/views.py from django.db import IntegrityError from django.shortcuts import render from django.contrib.auth.models import User def signupfunc(request): if request.method == 'POST': username = request.POST['username'] password = request.POST['password'] try: user = User.objects.create_user(username, '', password) return render(request, 'login.html', {}) except IntegrityError: return render(request, 'signup.html', {'error': 'このユーザはすでに登録されています'}) return render(request, 'signup.html', {})
これで登録(signup
)のView実装は完了です。
ログイン(login
)
次に、Django側でログイン(login
)のViewを実装します。_app/views.py
にアクセスして、以下のコードを書いてください。
#_app/views.py from django.db import IntegrityError from django.shortcuts import render, redirect from django.contrib.auth import authenticate, login from django.contrib.auth.models import User def signupfunc(request): if request.method == 'POST': username = request.POST['username'] password = request.POST['password'] try: user = User.objects.create_user(username, '', password) return render(request, 'login.html', {}) except IntegrityError: return render(request, 'signup.html', {'error': 'このユーザはすでに登録されています'}) return render(request, 'signup.html', {}) #追加 def loginfunc(request): if request.method == 'POST': username = request.POST['username'] password = request.POST['password'] user = authenticate(request, username=username, password=password) if user is not None: login(request, user) return redirect('index') else: return render(request, 'login.html', {}) return render(request, 'login.html', {})
ログアウト(logout
)
最後に、ログアウト(logout
)のViewを実装します。_app/views.py
に以下のコードを書いてください。
#_app/views.py #_app/views.py from django.db import IntegrityError from django.shortcuts import render, redirect from django.contrib.auth import authenticate, login, logout from django.contrib.auth.models import User from django.contrib.auth.decorators import login_required #忘れないように! def signupfunc(request): if request.method == 'POST': username = request.POST['username'] password = request.POST['password'] try: user = User.objects.create_user(username, '', password) return render(request, 'login.html', {}) except IntegrityError: return render(request, 'signup.html', {'error': 'このユーザはすでに登録されています'}) return render(request, 'signup.html', {}) def loginfunc(request): if request.method == 'POST': username = request.POST['username'] password = request.POST['password'] user = authenticate(request, username=username, password=password) if user is not None: login(request, user) return redirect('index') else: return render(request, 'login.html', {}) return render(request, 'login.html', {}) #追加 @login_required def index_func(request): return render(request, 'index.html', {}) def logoutfunc(request): logout(request) return redirect('login')
ルーティング設定
_app/views.py
で記述した処理をDjango側に反映させるために、_app/urls.py
に以下のコードを書いてください。
#_app/urls.py from django.urls import path from . import views urlpatterns = [ path('', views.index_func, name='index'), path('signup/', views.signupfunc, name='signup'), path('login/', views.loginfunc, name='login'), path('logout/', views.logoutfunc, name='logout'), ]
これでログイン機能を完全に実装できるようになりましたので、以下のコードを書いて実際に動かしてみてください。
$ python manage.py runserver
おわりに
今回の記事ではDjangoでログイン機能を実装する方法について詳細に解説しました。
次回の記事では、Djangoのテンプレートに投稿した内容の一覧を表示させるための方法を解説していきます。