djangoをdockerコンテナで利用(4) – ログイン画面作成

◆◆◆

ログインしないとページが見えないようなアプリケーションを構成する。

(1)(2)(3)では環境を作り、処理を作っていくための習作みたいなもの。

元々はphpで作って使っていたものを、djangoで作り直すのが目的。

phpで5年前に事務処理用で作ったものを、

php-web
php-web

djangoでこれから作り直す(円グラフはサンプルしかできてないけど・・・)。

php-web
php-web

やっとログイン画面と、その中のアプリの1つ目が使えるようになったのでその作成メモ。

ログインして見えるアプリケーションができるまで

「あーでもない、こーでもない」ってしばらく悩みながらdjangoいじった後、結局完成した後でgitの差分を見て書いてるのな。

アプリケーションとして「gvisWebApp」を追加して自動生成された内容に、★印の箇所を編集してった。

/code/app
|--gvisDjango3
|  (省略)
|--gvisWebApp
|  |--__init__.py
|  |--__pycache__
|  |--admin.py
|  |--apps.py
|  |--migrations
|  |--models.py
|  |--tests.py
|  |--urls.py ★
|  |--views.py ★
|  |--templates/gvisWebApp          ★手動作成
|  |  |--base.html                  ★手動作成
|  |  |--login.html                 ★手動作成
|  |  |--logout.html                ★手動作成
|  |  |--home.html                  ★手動作成
|  |  |--gvis_001_IntraIchiran.html ★手動作成
|--manage.py
|--requirements.txt 
|--templates
|  |--gvisDjango3
|  |  |--gvisDjango3Top.html
|--website
|  |--__init__.py
|  |--__pycache__
|  |--asgi.py
|  |--settings.py ★
|  |--static
|  |  |--admin
|  |--urls.py ★
|  |--wsgi.py

ログインはdjangoに基本機能があるらしい

phpのときはログイン画面を実装している人がたくさんおられたので、参考にして作った。

djangoの場合は自前で作ることも考えたけど、基本機能があるらしくセキュリティ的な穴もバージョンアップで防いでいってくれるならそれを使おうって考えた。

Django でのユーザー認証 | Django ドキュメント
The web framework for perfectionists with deadlines.

業務データはmariadbで持っているのに対し、django用にmysqlのコンテナも使っているので、そこをログイン機能だけが使ってくれるならいいかなって。

実際には、django使い始めの頃に見たadminのページに連動していて、ユーザはそこで作成したものが有効になる。

django-login
django-login

このdjangoの管理画面にログインしているときにアプリケーションとして作った画面をURL直接指定すると、ログインしているとみなされて表示される。

djangoの管理画面を開いておき、別タブでアプリケーションにログインしてログアウトすると、djangoの管理画面はログアウト状態になる。

で、実際に参考にさせてもらったページ。
作者さんありがとう。

404 Not Found - Qiita - Qiita
Djangoのログイン処理を実装する方法① | 知的好奇心
Djangoのログイン処理を実装する方法をご紹介します。ここではPyCharmを用いて以下の処理を作成します。 ログイン ログアウト条件 Django 2.1.3 Python 3.7.0 PyCharm Professionalプロジェク...

アプリケーションを追加

まずはdjangoにアプリケーションを追加。
dockerコンテナにbashログインして作るんだけど、エコー捨ててた。
投入したコマンドラインは以下のとおり。

nari@nafslinux-intra-gavann-it-com:/docker$ docker exec -it docker_sv_django_1 bash
root@svdjango:/# cd /code/app
root@svdjango:/# /usr/bin/python3 manage.py startapp gvisWebApp
:
:(中略)
:

すぐに業務DBの入ったmariadb読ませてアプリケーション作るわけじゃないけど、念のためマイグレーションもやったっけ。

/usr/bin/python3 manage.py makemigrations gvisWebApp
/usr/bin/python3 manage.py migrate gvisWebApp

作られたフォルダは、そのままではwindowsやmacから編集できないので、コンテナにbashログインした後で所有権を全部すげかえる。/code/appとしてマウントしている永続化領域にcdしてchownしとく。

root@svdjango:/# exit
nari@nafslinux-intra-gavann-it-com:/docker$ sudo su - 
nari@nafslinux-intra-gavann-it-com:~# cd /docker/nariDockerDat/sv_django-uwsgi-nginx/app
chown -R nari:nari gvisWebApp/

ログイン画面を表示させるためのソース修正

アプリケーション追加したら自動でフォルダが生成される。
プロジェクトのsettings.pyとurls.pyを修正し、アプリケーションの内容を修正してる。

website/settings.py

追加した1か所目の抜粋は以下のとおり。追加したアプリのapps.pyが自動生成されているから、その内容を参考に追記した。

INSTALLED_APPS = [
    'django.contrib.admin',
    'django.contrib.auth',
    'django.contrib.contenttypes',
    'django.contrib.sessions',
    'django.contrib.messages',
    'django.contrib.staticfiles',
    'django.contrib.humanize',              
    'gvisDjango3.apps.Gvisdjango3Config',   
    'gvisWebApp.apps.GviswebappConfig',     ★追記(ログイン画面用)
]

2か所目は、最初の頃にSTATIC_URLを書き足したことあるけど、django.contrib.authで使うURLの定義をアプリケーション名をからめて書く。

STATIC_URL = '/static/'
STATIC_ROOT = os.path.join(BASE_DIR, "website/static")

# ログイン・ログアウトのリダイレクトURL     ★ここから追記(ログイン画面用)
LOGIN_URL = '/gvisWebApp/login'
LOGIN_REDIRECT_URL = '/gvisWebApp/home'

website/urls.py

ブラウザからのリクエストをどこに振り分けるかって記述。

urlpatterns = [
    path('admin/', admin.site.urls),
    path('gvisDjango3/', include('gvisDjango3.urls')),
    path('gvisWebApp/', include('gvisWebApp.urls')),    ★追記(ログイン画面用)
]

gvisWebApp/urls.py

ログイン・ログアウト・ホーム画面の行き先みたいなのをそれぞれ定義。
参考ページにはログインのことが主に書いてあったので「LogoutView」が使えることを確認して書いた。

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

app_name = 'gvisWebApp' ★ここから追記(ログイン画面用)

urlpatterns = [
    path('login/', auth_views.LoginView.as_view(template_name='gvisWebApp/login.html'), name='login'),
    path('logout/', auth_views.LogoutView.as_view(template_name='gvisWebApp/logout.html'), name='logout'),
    path('home/', views.home, name="home"),
]

gvisWebApp/views.py

ブラウザからのリクエストに応答するための記述。
「@login_required」は、ログイン状態じゃなければ表示を許さないためのおまじない。
実際の挙動としては、ログインなしでURL直接指定で開こうとすると、ログイン画面が表示される。

from django.shortcuts import render
from django.contrib.auth.decorators import login_required

@login_required         ★ここから追記(ログイン画面用)
def home(request):
    return render(request, 'gvisWebApp/home.html')

@login_required
def gvis_001_IntraIchiran(request):
    return render(request, 'gvisWebApp/gvis_001_IntraIchiran.html')

phpでは「gvis_001_IntraIchiran」ではなく「001-IntraIchiran.php」ってファイル名で作ってた。

djangoでもファイル名に連動して処理名を書くんだけど、「001-」ってのが許してもらえないらしく、ちゃんと動かない。たぶんどっかのドキュメントに処理名や変数の名前制限が書いてあるんやろな。

そこで記号であるハイフンは、文字であるアンスコにし、ゼロから始めるのやめて「gvis」を先頭につけた。こうするとファイル一覧したときもまとまった位置に表示される。

gvisWebApp/templates/base.html

ここからのテンプレートは参考URLにあった内容をほぼ丸パクリ。
インクルードさせる元になる。全部のページのタイトルを統一したかったので、これでOK。

<!doctype html>
<html lang="ja">
  <head>
    <title>GavannITサービス</title>
    {% include "Header.html" %}
  </head>
  <body>
    {% block content %}
    {% endblock content %}
  </body>
</html>

gvisWebApp/templates/login.html

「form.as_p」と「<button>ログイン</button>」っていうのを書くだけでログインのためのテキスト入力ができてしまう。ああ楽チン。phpのときはけっこう苦しんだっけ。

{% extends 'gvisWebApp/base.html' %}
{% load static %}

{% block customcss %}
    <link rel='stylesheet' type='text/css' href="{% static 'admin/commonGreen/css/gvisGreen.css' %}">
{% endblock customcss %}

{% block header %}
{% endblock header %}

{% block content %}
  <body>

    <form class="form-login" action='' method='POST'>
    <h1>ログイン画面</h1>
    {% csrf_token %}

    {{ form.as_p }}

    <button>ログイン</button>
    </form>
  </body>
</html>
{% endblock content %}

gvisWebApp/templates/logout.html

このページを呼び出すとログアウトした状態になる。
ログイン画面へ行くボタンを設置。

{% extends 'gvisWebApp/base.html' %}
{% load static %}

{% block customcss %}
    <link rel='stylesheet' type='text/css' href="{% static 'admin/commonGreen/css/gvisGreen.css' %}">
{% endblock customcss %}

{% block header %}
{% endblock header %}

{% block content %}
  <body>

    <h1>ログアウト画面</h1>

    <button type=“button” onclick=location.href="{% url 'gvisWebApp:login' %}">ログイン画面へ</button>

  </body>
</html>
{% endblock content %}

gvisWebApp/templates/home.html

ログイン後に表示される画面。最初は以下の内容だったけど、今はphpの画面にかなり寄せた。

{% extends 'gvisWebApp/base.html' %}
{% load static %}

{% block customcss %}
    <link rel='stylesheet' type='text/css' href="{% static 'admin/commonGreen/css/gvisGreen.css' %}">
{% endblock customcss %}

{% block header %}
<title>ホーム画面</title>
{% endblock header %}

{% block content %}
<body>
  {% if user.is_authenticated %}
  こんにちは {{ user.username }}!
  <p><a href="{% url 'gvisWebApp:logout' %}">logout</a></p>
  {% else %}
  <p>ログインされていません</p>
  <a href="{% url 'gvisWebApp:login' %}">login</a>
{% endif %}
  </body>
{% endblock content %}

寄せた結果がコレ。単純に一覧表示するものを1つだけ作ったけど、phpから移植終わってない機能はボタンのキャプションに「(未)」をつけた。

{% extends 'gvisWebApp/base.html' %}
{% load static %}

{% block header %}
<title>ホーム画面</title>
{% endblock header %}

{% block content %}
<body>
  {% if user.is_authenticated %}
    ようこそ {{ user.last_name }} {{ user.first_name }} ({{ user.username }}) さん

    {# 参考URL #}
    {# https://docs.djangoproject.com/en/3.2/ref/contrib/auth/ #}
    {# https://www.webcreatorbox.com/tech/dark-mode #}
    {# https://opendata-web.site/blog/entry/6/ #}

    <center>
      <fieldset style="width:60%">
          <legend align="center">基盤管理</legend>
          <input class="darkmode-ignore" type="button" name="KibanURL_btn0" onclick="window.open('{% url 'gvisWebApp:gvis_001_IntraIchiran' %}' );" value="イントラ一覧" >
          <input class="darkmode-ignore" type="button" name="KibanURL_btn1" onclick="window.open('{% url 'gvisWebApp:gvis_001_IntraIchiran' %}' );" value="(未)資産一覧" >
          <input class="darkmode-ignore" type="button" name="KibanURL_btnLog" onclick="window.open('{% url 'gvisWebApp:gvis_001_IntraIchiran' %}' );" value="(未)操作ログ" >
      </fieldset>
      <fieldset style="width:60%">
          <legend align="center">取引管理</legend>
          <input class="darkmode-ignore" type="button" name="MakerURL_btn2" onclick="window.open('{% url 'gvisWebApp:gvis_001_IntraIchiran' %}' );" value="(未)顧客一覧" >
          <input class="darkmode-ignore" type="button" name="MakerURL_btn3" onclick="window.open('{% url 'gvisWebApp:gvis_001_IntraIchiran' %}' );" value="(未)取引一覧" >
      </fieldset>
      <fieldset style="width:60%">
          <legend align="center">経理業務</legend>
          <input class="darkmode-ignore" type="button" name="MakerURL_btn4" onclick="window.open('{% url 'gvisWebApp:gvis_001_IntraIchiran' %}' );" value="(未)活動&受注一覧" >
          <input class="darkmode-ignore" type="button" name="MakerURL_btn5" onclick="window.open('{% url 'gvisWebApp:gvis_001_IntraIchiran' %}' );" value="(未)会議一覧" >
          <input class="darkmode-ignore" type="button" name="MakerURL_btn6" onclick="window.open('{% url 'gvisWebApp:gvis_001_IntraIchiran' %}' );" value="(未)経費一覧" >
          <input class="darkmode-ignore" type="button" name="MakerURL_btn7" onclick="window.open('{% url 'gvisWebApp:gvis_001_IntraIchiran' %}' );" value="(未)科目単位経費一覧" >
          <br>
          <input class="darkmode-ignore" type="button" name="MakerURL_btn8" onclick="window.open('{% url 'gvisWebApp:gvis_001_IntraIchiran' %}' );" value="(未)年度-総勘定元帳" >
      </fieldset>
      <fieldset style="width:60%">
          <legend align="center">台帳管理-保存期間7年</legend>
          <input class="darkmode-ignore" type="button" name="Shinkoku1URL_btn" onclick="window.open('http://nafslinux.intra.gavann-it.com/svm/Public/100_会社/GavannITサービス/01_固定データ/20140618青色申告承認申請.pdf')"  value="青色申告申請" >
          <input class="darkmode-ignore" type="button" name="Shinkoku2URL_btn" onclick="window.open('http://nafslinux.intra.gavann-it.com/svm/Public/100_会社/GavannITサービス/01_固定データ/20140929_青色事業者専従者給与に関する届出書.jpg')"  value="青色事業者専従者給与届出書" >
          <br> 
          <br>
          【主要帳簿】
          <input class="darkmode-ignore" type="button" name="DaichoURL_btn3" onclick="window.open('{% url 'gvisWebApp:gvis_001_IntraIchiran' %}' );" value="(未)仕分帳" > 
          <br>
          【補助帳簿】
          <input class="darkmode-ignore" type="button" name="DaichoURL_btn1" onclick="window.open('{% url 'gvisWebApp:gvis_001_IntraIchiran' %}' );" value="(未)固定資産台帳" >
          <input class="darkmode-ignore" type="button" name="DaichoURL_btn2" onclick="window.open('{% url 'gvisWebApp:gvis_001_IntraIchiran' %}' );" value="(未)現金出納帳" > 
          <br> 
          <input class="darkmode-ignore" type="button" name="KokuzeiURL_btn" onclick="window.open('https://www.nta.go.jp/')"  value="国税庁" > 
          <br>
          <input class="darkmode-ignore" type="button" name="KokuzeiURL_btn" onclick="window.open('https://www.keisan.nta.go.jp/h28/ta_top.htm')"  value="申告作成コーナーのページ" >
      </fieldset>
    </center>

    {% else %}
      <p>ログインされていません</p>
      <a href="{% url 'gvisWebApp:login' %}">login</a>
    {% endif %}
</body>
{% endblock content %}

gvisWebApp/templates/gvis_001_IntraIchiran

これはアプリケーション。
めっちゃ長いので一部だけ。

{% extends 'gvisWebApp/base.html' %}
{% load static %}

{% block content %}
<body>
  <center>

    <table border=4 align=center>
    <caption>GVIS-winVM</caption>
    <tr bgcolor="#cccccc">
            <th>ノード</th>
            <th>IP</th>
            <tr align=left>

  <td align=left>nari-win2k</td>              
  <td align=left>192.168. 1.011</td></tr>
  <td align=left>nari-win98</td>    
:
:(中略)
:
  <td align=left>gakky-win10</td>
  <td align=left>895432527</td></tr>

            </tr>
    </table>
<br>
<br>

</center>

</body>
{% endblock content %}

ログインしてみる

ログイン画面はこんな感じ。おお、開くやん。

django-login

間違えて入力したら、ちゃんと警告してくれる。イントラ利用やし、意地悪テストはまた今度。

django-login

実際にログインしてみると、、、やったー!! 開いたやん!!
最初開けたときはめっちゃ嬉しかった。

django-login

ログインせずにアプリケーションを開いてみる

ログインしてない状態で、「イントラ一覧」のURLを直接開くと、、、ちゃんとログイン画面になる。

django-login

ここでログインするとき、URLには「next」って文字が見える。

https://nafslinux.intra.gavann-it.com:30443/gvisWebApp/login/?next=/gvisWebApp/gvis_001_IntraIchiran/

ログインしてみると、「イントラ一覧」のgvis_001_intraIchiranが開く。

django-login

今はこのあたりまででOK。残りの移植はまた今度。

vscodeでdjango編集してたら赤い波線がいっぱい

ここまでやってきて、templatesの中にあるhtmlファイルをvscodeで見たら赤くなってるのに気づいた。なんか言うとるなぁぐらいに思ってたけど、よく見たらjavascriptの記述あたりに波線がついてる。

vscode-red

しばらく「問題」の窓開けてなかったけど、開いてみると「カンマ書いてちょ」って赤い×表示がズラズラ。せっかくログイン画面使えるようになったとこやのに、なんかハラ立つわー。

vscode-red

javascript的に書き方がアカンってことなんやろけど、シングルクオートの中に、別のシングルクオートのかたまりがあるからなんやろなぁ。

onclick="window.open('{% url 'gvisWebApp:gvis_001_IntraIchiran' %}' );" 

せやけど、どっちにも書きたいし、vscodeの構文チェック(lint)の制御したらええんかな。lintってc言語であったけど、djangoでは何て言うんや?

無理に制御するのはあんまり好かない。そういえばvscodeの拡張機能入れたらなんとかなるかもなぁーと思って、探してみたらいっぱいあるやん。

いっぱいあるけど、どれ使えっちゅーねん。

vscode-red

あんまり深く考えず、1つ目のに「beautiful syntax」ってあるから使ってみた。
拡張機能インストールしてvscode再起動してみたら、

vscode-red

真っ赤やった表示が、あっさり消えた。
こんなんで解決してええんか?

ま、問題出たらまた考えるっちゅーことで。

タイトルとURLをコピーしました