投稿日: | 最終更新日:
Userモデルをカスタマイズしてプロフィール情報を追加する(Django)
Vagrantで作ったCentOS7のAnaconda・Django環境に、ユーザ登録ページを作成しました。今回は、Userモデルをカスタマイズして、ユーザ情報を拡張します。
Userモデルをカスタマイズ
前回、自作のユーザ登録、ユーザ情報変更、パスワード変更を作りました。今回は、以下のようなユーザ情報を拡張してUserモデルに無い情報を追加します。
DjangoのUserモデルには、住所や電話番号などの属性はありません。シンプルにUserモデルと紐づくProfileモデルを作成し、Userモデルにない情報を紐づけます。
前回から引き継ぐページ
トップページ (/index) |
ドメイン直下のページです。ログイン前はページタイトルのみですが、ログインすると、ヘッダーナビゲーションにようこそ○○さんと表示します。 |
---|---|
プロフィール (/profile) |
ログインているユーザ(自分自身)の情報を表示します。ログイン前の状態の場合、ログインページへ遷移します。 |
ログイン (/login) |
ユーザ名とパスワードを入力してログインします。ログインが完了すると、ログイン状態になってトップページへ遷移します。 |
ログアウト (/logout) |
ログアウト状態にしてトップページへ遷移します。 |
ユーザ登録ページ (/new) |
ユーザ登録をします。登録が完了すると、ログイン状態にしてトップページへ遷移します。 |
ユーザ情報変更ページ (/change_data) |
ユーザ情報を変更します。このページではパスワードを変更できません。ログイン前の状態の場合、ログインページへ遷移します。 |
パスワード変更ページ (/change_password) |
パスワード変更ページを変更します。ログイン前の状態の場合、ログインページへ遷移します。 |
今回作る(変更する)ページ
ユーザ登録ページ(/new) | ユーザ登録をします。登録が完了すると、ログイン状態にしてトップページへ遷移します。 |
---|---|
プロフィール (/profile) |
ログインているユーザ(自分自身)の情報を表示します。ログイン前の状態の場合、ログインページへ遷移します。このページに性別と電話番号を追加します。 |
仕様
前回から引き継ぐページ
トップページです。「ドメイン/」にアクセスします。
ログインページです。「ドメイン/login」にアクセスします。
ログインページからログインした場合は「ドメイン/」(トップページ)へ遷移します。
プロフィールページです。「ドメイン/profile」にアクセスします。ログイン中のユーザの情報を表示します。
ログアウトを押すと、ログアウト処理後トップページへリダイレクトします。
ユーザ情報変更ページです。変更後、トップページへリダイレクトします。
パスワード変更ページです。変更後、トップページへリダイレクトします。
今回作る(変更する)ページ
ユーザ登録ページです。性別と電話番号フォームを追加しました。
プロフィールページです。性別と電話番号フォームを追加しました。
準備
Vagrantでゲスト環境(仮想環境)を作ります。
①Virtualboxをインストールします。Virtualboxのインストールまでで結構です。
→VirtualBoxをインストールする for Ubuntu
②Vagrantをインストールします。centos7環境を作りますので、Vagrantのインストールのみ済ませてください。
→Vagrantをインストールしてテスト環境を作る for Ubuntu
Vagrantのcentos7環境の詳細を調べる場合は以下のように確認します。
→VagrantのCentOS7の環境を確認(lsb_releaseコマンドなど)
③バージョン管理ツールのpyenvインストールします。Anacondaインストールに使います。
→VagrantのCentOS7にバージョン管理ツールをインストール(pyenv)
④Anaconda・Djangoインストールします。
→Vgrant(CentOS7)にAnaconda+Django+Apache環境を作る(Anaconda・Djangoインストール)
⑤mariadb、mod_wsgiをインストールし、apacheで動作するように設定します。
→Vgrant(CentOS7)にAnaconda+Django+Apache環境を作る(MariaDBのインストール・設定)
⑥管理画面(admin)にCSSを適用します。
→Vgrant(CentOS7)にAnaconda+Django+Apache環境を作る(管理画面のCSS)
⑦Bootstrapをインストールします。
→VagrantのDjangoで作るWebアプリケーション(その6 Bootstrapのインストール)
⑧自作のログインページを作成します。
⑨ユーザ登録ページを作成します。
⑩Userモデルを使用してユーザ情報変更ページとパスワード変更ページを作ります。
→Userモデルを使用してユーザ情報変更ページとパスワード変更ページを作る(Django)
ホスト環境
OS | Ubuntu 16.04.1 LTS 64bit |
---|---|
Virtualbox | 5.1 |
Vagrant | 1.9.5 |
ゲスト環境
OS | CentOS 7.1.1503 |
---|---|
pyenv | 1.1.3-5-g7dae197 |
Anaconda | 3-4.3.0 |
MariaDB | 5.5.52-1.el7 |
Apache | 2.4.6 |
mod_wsgi | 4.5.14 |
Vagrantへログイン
①【ホスト環境】端末を開き、前回構築したVagrantのディレクトリまで移動します。
cd vagrant/django_apps/
②【ホスト環境】仮想マシンを起動します。
vagrant up
③【ホスト環境】ログインします。
vagrant ssh
プロジェクトの設定
プロジェクトディレクトリを「pj」、アプリケーションディレクトリを「app1」とします。プロジェクトの設定は、前回と同じです。
モデルの設定
①models.pyを編集します。
vi pj/app1/models.py
以下のように編集します。Profileクラスを作り、電話番号と性別を追加します。性別は、セレクトボックスになります。
from django.contrib.auth.models import User from django.db import models GENDER_CHOICES = ( ("女性", "女性"), ("男性", "男性"), ) class Profile(models.Model): phone = models.CharField("電話番号", max_length=255, blank=True) gendar = models.CharField("性別", max_length=2, choices=GENDER_CHOICES, blank=True) user = models.OneToOneField(User) def __str__(self): return self.user
・「OneToOne」を追加します。これにより、profile.userやuser.profileとすることで、相互に呼び出すことができます。
user = models.OneToOneField(User)
③makemigrationsを実行します。
python pj1/manage.py makemigrations app1
以下のような結果が表示されます。
Migrations for 'app1': pj1/app1/migrations/0002_profile.py - Create model Profile
④実行されるSQLを確認します。
python pj1/manage.py sqlmigrate app1 0002
以下のような結果が表示されます。
BEGIN; -- -- Create model Profile -- CREATE TABLE `app1_profile` (`id` integer AUTO_INCREMENT NOT NULL PRIMARY KEY, `phone` varchar(255) NOT NULL, `gendar` varchar(2) NOT NULL, `user_id` integer NOT NULL UNIQUE); ALTER TABLE `app1_profile` ADD CONSTRAINT `app1_profile_user_id_04d51e3a_fk_auth_user_id` FOREIGN KEY (`user_id`) REFERENCES `auth_user` (`id`); COMMIT;
⑤migrateを実行します。
python pj1/manage.py migrate
以下のような結果が表示されます。
Operations to perform: Apply all migrations: admin, app1, auth, contenttypes, sessions Running migrations: Applying app1.0002_profile... OK
アプリケーションの設定
①forms.pyを編集します。
vi pj/app1/forms.py
前回のforms.pyに加えて、以下の内容を追加します。
from django import forms from django.contrib.auth.forms import UserCreationForm from .models import Profile ・・・省略・・・ class UserCreateForm(UserCreationForm): ・・・省略・・・ class ProfileForm(forms.ModelForm): def __init__(self, *args, **kwargs): super().__init__(*args, **kwargs) self.fields['gendar'].widget.attrs['class'] = 'form-control' self.fields['phone'].widget.attrs['class'] = 'form-control' class Meta: model = Profile fields = ( "gendar", "phone" )
②アプリケーションディレクトリのviews.pyを編集します。
vi pj1/app1/views.py
前回のviews.pyに加えて、以下の内容を追加します。(new関数を変更します。)
from django.contrib.auth import login from django.shortcuts import render, redirect from .forms import ProfileForm, UserCreateForm ・・・省略・・・ def new(request): form = UserCreateForm(request.POST or None) profile_form = ProfileForm(request.POST or None) if request.method == "POST" and form.is_valid() and profile_form.is_valid(): #Userモデル処理 user = form.save(commit=False) user.is_staff = True user.save() #Profileモデルの処理 profile = profile_form.save(commit=False) profile.user = user profile.save() login( request, user, backend="django.contrib.auth.backends.ModelBackend") return redirect("app1:index") context = { "form": form, "profile_form": profile_form, } return render(request, 'form.html', context) ・・・省略・・・
templateへ複数のフォームを渡すことができます。またそれを受け取ることも可能です。
・・・省略・・・ form = UserCreateForm(request.POST or None) profile_form = ProfileForm(request.POST or None) ・・・省略・・・ context = { "form": form, "profile_form": profile_form, } return render(request, 'form.html', context) ・・・省略・・・
Userモデルを作成します。「commit=False」は、データベースには保存せず、保存する前のモデルオブジェクトを返します。よって、「user.is_staff」等のアクセスが可能です。
# Userモデルの処理。ログインできるようis_staffをTrueにし保存 user = form.save(commit=False) user.is_staff = True user.save()
.save(commit=False) : 保存すると、モデルオブジェクトが得られます。
is_staff : この値が真なら、ユーザは admin サイトにアクセスできます。
「login()」でログインします。すでにユーザ名・パスワードが存在する場合は、先に「authenticate()」を呼び出しますが、ここでは新規にユーザを作りますので呼び出しません。「authenticate()」を使わずにログインさせる場合はbackendを必ず指定します。ここで指定する「django.contrib.auth.backends.ModelBackend」は、Djangoのデフォルトのバックエンドです。
login( request, user, backend="django.contrib.auth.backends.ModelBackend")
ユーザをログインさせるには、ビューの中でこの関数を使います。この関数は、HttpRequestオブジェクトとUserオブジェクトを引数にとります。login()は、Djangoのセッションフレームワークを使って、ユーザのIDをセッションに保存します。従って、セッションミドルウェアをインストールしておかねばなりません。
・authenticate()
ユーザを手動でログインさせる場合、「login()」を呼び出す前に必ず 「authenticate()」を呼び出してください。「authenticate()」は、Userオブジェクトに、そのユーザが 認証バックエンドによって正しく認証されたことを示す属性を付加します。この情報が後々ログイン処理で必要になります。
テンプレートの設定
アプリケーションディレクトリ配下のtemplatesディレクトリへhtmlテンプレートを作成します。
base.html、index.html、login.html、logout.html、profile.htmlは前回と同じです。
①form.htmlを変更します。
vi pj1/app1/templates/form.html
以下のように記述します。
{% extends "base.html" %} {% block content %} <form class="my-form" action="" method="POST"> <div class="form-group"> <label for="id_username">ユーザネーム</label> {{ form.username }} {{ form.username.errors }} <p class="help-block">{{ form.username.help_text }}</p> </div> <div class="form-group"> <label for="id_email">Email</label> {{ form.email }} {{ form.email.errors }} <p class="help-block">{{ form.email.help_text }}</p> </div> <div class="form-group"> <label class="control-label" for="id_password1">パスワード</label> {{ form.password1 }} {{ form.password1.errors }} </div> <div class="form-group"> <label class="control-label" for="id_password2">パスワード(確認)</label> {{ form.password2 }} {{ form.password2.errors }} <p class="help-block">{{ form.password2.help_text }}</p> </div> <div class="form-group"> <label for="id_firstname">FirstName</label> {{ form.first_name }} {{ form.first_name.errors }} <p class="help-block">{{ form.first_name.help_text }}</p> </div> <div class="form-group"> <label for="id_firstname">FirstName</label> {{ form.first_name }} {{ form.first_name.errors }} <p class="help-block">{{ form.first_name.help_text }}</p> </div> <div class="form-group"> <label for="id_lastname">LastName</label> {{ form.last_name }} {{ form.last_name.errors }} <p class="help-block">{{ form.last_name.help_text }}</p> </div> <div class="form-group"> <label for="id_gendar">性別</label> {{ profile_form.gendar }} </div> <div class="form-group"> <label for="id_phone">電話番号</label> {{ profile_form.phone }} </div> <div class="form-group"> <div> <input type="submit" class="btn btn-default" value="登録"> </div> </div> {% csrf_token %} </form> {% endblock %}
②profile.htmlを変更します。
vi pj1/app1/templates/profile.html
以下のように記述します。
{% extends "base.html" %} {% block content %} user.username(名前) : {{ user.username }}<hr> user.is_staff(/adminにログインできるか) : {{ user.is_staff }}<hr> user.is_active(アカウントはアクティブか、通常のログインはできるか) : {{ user.is_active }}<hr> user.is_superuser(すうぱあゆうざあ ですか) : {{ user.is_superuser }}<hr> user.last_login(最期のログイン) : {{ user.last_login }}<hr> user.date_joined(アカウントの作られた日) : {{ user.date_joined }}<hr> 性別:{{ user.profile.gendar }}<br> 電話:{{ user.profile.phone }}<br> {% endblock %}
- Python 113
- 制作 54
- RaspberryPi 41
- Django 40
- WordPress 40
- Linux 27
- VPS 22
- JavaScript 21
- PHP 20
- HTML・CSS 19
- AWS 16
- 仮想環境 15
- レスポンシブデザイン 13
- マイコン 11
- WEB全般 11
- 動画製作 9
- Webサービス 8
- 統合開発環境 8
- PyCharm 7
- jQuery 7
- 機械学習 7
- AfterEffects 7
- 起業・設立 7
- Django REST framework 6
- C# 6
- デザイン 6
- SEO 6
- pydata 6
- Visual Studio 5
- 数学 5
- 携帯サイト 5
- heroku 5
- Mac 5
- illustrator 5
- node.js 5
- Anaconda 5
- Nginx 4
- Jupyter Notebook 4
- インフラ 4
- symfony 4
- Webスクレイピング 3
- photoshop 3
- Go言語 3
- PC 3
- Google Colaboratory 3
- ツール 3
- Docker 3
- facebook 3
- 作業効率化 3
- データベース 3
- Cloud9 3
- コマンド 2
- micro:bit 2
- Kali Linux 2
- Webサーバー 2
- MariaDB 2
- ドローン 2
- コンテナ 2
- DaVinci Resolve 2
- ネットワーク 2
- Java 2
- movie 2
- PCDJ 2
- 音楽 2
- XSERVER 2
- Ansible 1
- Vue.js 1
- JSON 1
- Bootstrap 1
- バージョン管理システム 1
- SSL 1
- S3 1
- ムームードメイン 1
- ネットワーク 1
- アニメーション 1
- D3.js 1
- Rhino 1
- アニメ 1
- git 1
- windows 1
- アクセス解析 1
- スマートフォン 1
- アフィリエイトノウハウ 1
- 知識 1
- TypeScript 1
- 役立つ本・書籍 1
- データサイエンス 1
- ESP32 1
- AI 1
- ownCloud 1
- API 1