Django でユーザー認証付きの Hello World

ユーザー認証をつけた Hello World です。
データベースは MariaDB を使います。

完成時は次のようなフォルダー構造になります。

```text
proj01
├── accounts
│   ├── admin.py
│   ├── apps.py
│   ├── migrations
│   ├── models.py
│   ├── tests.py
│   └── views.py
├── home
│   ├── admin.py
│   ├── apps.py
│   ├── migrations
│   ├── models.py
│   ├── tests.py
│   ├── urls.py
│   └── views.py
├── manage.py
├── proj01
│   ├── asgi.py
│   ├── settings.py
│   ├── urls.py
│   └── wsgi.py
└── templates
    └── registration
        ├── base.html
        ├── logged_out.html
        └── login.html
```

#プロジェクトの作成#

```bash
django-admin startproject proj01
cd proj01/
python manage.py migrate
python manage.py startapp home
```

>この時点で開発サーバーを動かしてみます。

```bash
gunicorn proj01.wsgi
```

>ブラウザーで　http://127.0.0.1:8000/　にアクセス

#表示するページの作成#

```py:home/view.py
from django.http import HttpResponse
from django.contrib.auth.decorators import login_required

# @login_required
def index(request):
    str_out = ""
    str_out += "<p>*** home *** start ***</p>"
    str_out += "<p>ホームです。</p>"
    str_out += '<p><a href="accounts/logout/">Logout</a></p>'
    str_out += "<p>*** Nov/09/2021 AM 08:38 ***</p>"
    str_out += "<p>*** home *** end ***</p>"
    return HttpResponse(str_out)
```

```py:proj01/settings.py
(省略）
INSTALLED_APPS = [
    'home',
    'django.contrib.admin',
    'django.contrib.auth',
    'django.contrib.contenttypes',
    'django.contrib.sessions',
    'django.contrib.messages',
    'django.contrib.staticfiles',
]
(省略）
LANGUAGE_CODE = 'ja'
TIME_ZONE = 'Asia/Tokyo'
(省略）
```

```py:proj01/urls.py
from django.contrib import admin
from django.urls import include
from django.urls import path

urlpatterns = [
#    path('accounts/', include('django.contrib.auth.urls')),
    path('', include('home.urls')),
    path('admin/', admin.site.urls),
]
```

```py:home/urls.py
from django.urls import path

from . import views

urlpatterns = [
    path('', views.index, name='index'),
]
```

>再びサーバーを動かします。

```bash
gunicorn proj01.wsgi
```

#データベースを MariaDB に切り替え#

```py:proj01/settings.py
(省略）
DATABASES = {
    'default': {
        'ENGINE': 'django.db.backends.mysql',
        'NAME': 'django',
        'USER': 'django',
        'PASSWORD': 'tiger123',
        'HOST': 'localhost',
        'PORT': '3306',
        'OPTIONS': {
                'init_command': "SET sql_mode='STRICT_TRANS_TABLES'",
                },
    }
(省略）
```

設定の変更を反映

```bash
python manage.py migrate
````

#スーパーユーザーの作成#

```text
$ python manage.py createsuperuser
ユーザー名 (leave blank to use 'uchida'): admin
メールアドレス: test@test.com
Password: 
Password (again): 
```

>再びサーバーを動かします。

```bash
gunicorn proj01.wsgi
```

ブラウザーで http://127.0.0.1:8000/admin/ にアクセスして、ログインユーザーを作成する。
![django_nov09_bb.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/179446/a0419942-16a2-e5f6-c970-c9e92a0586dd.png)

作成したユーザーは次のようにして確認できます。

```text
$ python manage.py dbshell


MariaDB [django]> select username from auth_user;
+----------+
| username |
+----------+
| admin    |
| betty    |
| jack     |
| scott    |
+----------+
4 rows in set (0.000 sec)
```

#login ページの作成#

テンプレートの作成

フォルダーの作成

```bash
mkdir templates
mkdir templates/registration
```

```html:templates/registration/base.html
{% load static %}
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>Django System</title>
</head>
<body>
<div class="container">
    <div class="content">
        {% block content %}{% endblock %}
    </div>
</div>
</body>
</html>
```

```html:templates/registration/login.html
{% extends 'registration/base.html' %}

{% block title %}Login{% endblock %}

{% block content %}
<h1>Login</h1>
<section class="common-form">
    {% if form.errors %}
    <p class="error-msg">Your username and password didn't match. Please try again.</p>
    {% endif %}

    {% if next %}
    {% if user.is_authenticated %}
    <p class="error-msg">Your account doesn't have access to this page. To proceed,
        please login with an account that has access.</p>
    {% else %}
    <p class="error-msg">Please login to see this page.</p>
    {% endif %}
    {% endif %}

    <form method="post" action="{% url 'login' %}">
        {% csrf_token %}
        {{ form.as_p }}
        <button type="submit" class="submit">Login</button>
        <input type="hidden" name="next" value="{{ next }}"/>
    </form>
</section>
{% endblock %}
```

```html:templates/registration/logged_out.html
{% extends 'registration/base.html' %}

{% block title %}Logout{% endblock %}

{% block content %}
<h1>Logged Out</h1>
<p>Thanks for spending some quality time with the Web site today.</p>
<p><a href="{% url 'login' %}">Log in again</a></p>
{% endblock %}
```

home/view.py を修正します。

```py:home/view.py
from django.http import HttpResponse
from django.contrib.auth.decorators import login_required

@login_required
def index(request):
    str_out = ""
    str_out += "<p>*** home *** start ***</p>"
    str_out += "<p>ホームです。</p>"
    str_out += '<p><a href="accounts/logout/">Logout</a></p>'
    str_out += "<p>*** Nov/09/2021 AM 08:38 ***</p>"
    str_out += "<p>*** home *** end ***</p>"
    return HttpResponse(str_out)
```

#accounts というアプリを作成#

```bash
python manage.py startapp accounts
```

proj01/urls.py を修正

```py:proj01/urls.py
from django.contrib import admin
from django.urls import include
from django.urls import path

urlpatterns = [
    path('accounts/', include('django.contrib.auth.urls')),
    path('', include('home.urls')),
    path('admin/', admin.site.urls),
]
```

Logout を実装

```py:proc01/settings.py
（省略）
LOGIN_REDIRECT_URL = '/'
```



>再びサーバーを動かします。

```bash
gunicorn proj01.wsgi
```

![django_nov09_aa.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/179446/e14e7529-d24c-bc83-ce07-d932335c3f4f.png)

ログインユーザーは、
http://127.0.0.1:8000/admin/
で登録したものを使います。