diadia

興味があることをやってみる。自分のメモを残しておきます。

models.pyまとめ

関連記事

models.pyを初めて使う場合の粗すぎる大枠

Django model.pyを初めて使う人向けに - diadia


field()のオプションについて

概要:()の中身の種類
https://docs.djangoproject.com/ja/2.1/ref/models/fields/#field-options



foreignkey, ManyToManyField,OneToOneFieldについて

モデルとモデルを紐付けるときに使う。
クエリセットの方法とかこちらがわかりやすい。
ManyToMany フィルターなどのオブジェクト操作一覧 - Django2の実力をつけるチュートリアルサイトDjangoBrothers[ジャンゴブラザーズ]

static fileを表示させる方法

staticの設定方法は前回書いた。

Django Static file の設定方法(settings.py) - diadia

次にhtmlにどのように書けばファイルが反映されるかを整理したい。

必要な要素は2点。
staticを宣言すること(実際には何も分かっていない)
画像、CSSのパスを書くこと


staticを宣言すること、は<!DOCTYPE html>よりも上に{% load static %}と書くことだ。

次にパスを書く。こんな感じ

CSSの場合、headに記載(bootstrapの一番下に記載)

<link rel="stylesheet"  href="{% static "hoge_holder/hoge.css" %}">
<img src= "{% static "hoge_holder/hoge.jpg" %}" class="img-fluid/>

Django Static file の設定方法(settings.py)

settings.py で設定する項目
STATIC_URL = '/static/'
MEDIA_URL = '/media/"
STATICFILES_DIR =[ os.path.join(BASE_DIR, "static_xxx")]
STATIC_ROOT =os.path.join(os.path.dirname(BASE_DIR), "static_yyy",static_root)
MEDIA_ROOT =os.path.join(os.path.dirname(BASE_DIR), "static_yyy",media_root)

の設定が必要。

設定が終わったら、ドキュメントに従ってurls.pyの設定も行う。
Managing static files (e.g. images, JavaScript, CSS) | Django documentation | Django

if urlpatterns.DEBUG:
urlpatterns = [
       path("",XXXXX),
       path("",XXXXX),
       path("",XXXXX),
] + static(settings.STATIC_URL, document_root=settings.STATIC_ROOT)
+ static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT)

ここまで出来たらpython manage.py collectstaticを用いること。
adminにアクセスするとデフォルトでstatic ,cssとgetの中に表示される。
これが自分で作ったページでも反映されれば設定は成功していると思って良い。

で、これらがどんな役割を果たすのか分からない。いろいろ情報を漁った結果、開発環境とプロダクト環境ではstaticファイルの扱い方が変わるらしい。
開発環境ではdjangoが直接staticファイルを扱うのに対し、本番環境ではnginxやapache等のwebサーバーがstaticファイルを扱うようなことが書いてあった。
そこでとりあえず仮定を立てる。
STATICFILES_DIRさえあれば開発環境は動くのか?また本番環境のフォルダを消したりして動くかやってみる。またpython manage.py collectstaticとは、どのような動きをするかも観察する。


ローカル環境の場合には最低限必要な要素は、STATICFILES_DIRとSTATIC_URLの設定のみで動いた。またurls.pyのurlpatterns= [path()...] +static...のstatic部分も設定しなかったけど動いてしまった。htmlを確認すると、staticが使われていた。static_urlはこの働きをするっぽい。
本番環境でstatic_rootが必要らしい。
静的ファイルのデプロイ | Django ドキュメント | Django


mediaについて
これもまだわかっていない事項ではあるが、staticとmediaの違いがわかったかもしれない。staticはcss,javascriptに加え、画像も配信することができる。mediaはあるモデルのオブジェクトに。

ユーザ登録(sign up)機能を作る

どうやってユーザを作成するか。
とりあえず作り方のアプローチとしては2通りある。
djangoビルトインのUserCreationFormを使う方法
Djangoの認証システムを使用する | Django documentation | Django

forms.pyから作成する方法(自作)



自作する方法を前半で、ビルトインのUserCreationFormを後半に記す。
注意:この方法ではuserのパスワードを保存できるかまだ確認中。userのパスワードを確実に保存したいのであればビルトインのUserCreationFormを使う方法をおすすめする。 


Djangoの認証システムを使用する | Django documentation | Django
この辺が必要になる。

views.pyにて

User = get_user_model()

def register_page():
    form = RegisterForm(request.POST)
    context = {"forms":form}
    
    if form.is_valid():
        print(form.cleaned_data)
        username = form.cleaned_data.get("username")
        email = form.cleaned_data.get("email")
        password = form.cleaned_data.get("password")
    new_user = User.objects.create_user(username, email,password )
    render(request, "register_page.html", context)

get_user_model()は使うことが推奨されている。

forms.py

from django import forms

class RegisterForm(foms.Form): 
    username = forms.CharField()
    email = forms.CharField()
    password = forms.CharField(widget=forms.PasswordInput)    
    password2=forms.CharField(
              label="ConfirmPassword",
              widget=forms.PasswordInput
                )
#フォームには入力ミス(バリデーションエラー)を表示させる機能を書く
#入力ミスの種類には、2箇所のパスワード入力値が不一致の場合に知らせるもの、すでに登録されているusername,emailの場合登録できないと知らせるものがある。

#password 不一致のバリデーション
    def match_password(self):
        data = self.cleaned_data.
        password = data.get("password")
        password2 = data.get("password2")
        if password != password2 :
            raise ValidationError("password must be same" )
        return data

#既登録の入力値エラー
    def double_email(self):
        email = self.cleaned_data.get("email")
        query_set = User.objects.filter(email=email)
        if email = query_set:
            return ValidationError("this e-mail is taken")
        return email

    def double_email(self):
        username = self.cleaned_data.get("username")
        query_set = User.objects.filter(username=username)
        if username = query_set:
            return ValidationError("this username is taken")
        return username

簡単にまとめると、登録機能はviews.pyが担っている。一方、forms.pyは入力内容を決めている。また入力値が適正かの判断もforms.pyが担っている。
登録機能の要views.pyについて少し書く。
create_user()で登録させる。引数はusername,email,passwordにした。
new_user = User.objects.create_user(username, email, password) のUserについては予め定義しておく。
User = get_user_model() これをしておかないと、djangoの既設定Userをつかってしまうからっぽい。username, email, passwordはいつもどおりに取り出す。(POSTの値をcleaned_dataして辞書型のデータに整形し、get()にキーを入力して取り出すって流れ。)




UserCreationFormを使う方法
既存のUserモデルを使ってsign up機能を実装するにはUserCreationFormを用いると良いと思っている。それはユーザーのパスワードを確実に登録できるからだ。
password = request.POST.get("password") や password = form.cleaned_data.get("password")と設定した変数passwordを扱ってuserをcreateすることが経験上うまくいかなかったからだ。単純に勘違いの可能性もあるが、今はpasswordの変数を使わないでuserインスタンスを発行するのが望ましいと結論づけている。
passwordの変数を使わないでuserインスタンスを発行するとは、User.objects.create_user(****)やUser.objects.create(****)を使わないでユーザーを作るということだ。
どうやらdjangoではuserモデルに関わるものはすでにいろいろなプログラムが準備されており、そのプログラムがあることでDjangoユーザーは自分の思い通りにコードを書くことができない。djangoを思い通りに使いたい場合にはUserモデル周辺の仕組みがどうなっているかを理解していくことが重要だと認識するようになった。

参考
https://simpleisbetterthancomplex.com/tutorial/2017/02/18/how-to-create-user-sign-up-view.html
https://overiq.com/django/1.10/django-creating-users-using-usercreationform/

https://docs.djangoproject.com/ja/2.1/topics/auth/passwords/

from django.shortcuts import render
from django.contrib.auth.models import User
from django.contrib.auth.forms import UserCreationForm
from django.contrib.auth import login, authenticate




def home(request):
	if request.method == "POST":
		form = UserCreationForm(request.POST)
		if form.is_valid():
			form.save()
#新事実!form.save()した段階でuserインスタンスが作成されている!!!
#以下のコードは登録した後に自動でログインする仕組みを書いているに過ぎない。
			username = form.cleaned_data.get("username")
			password = form.cleaned_data.get("password1")
			new_user = authenticate(username=username, password=password)
			login(request, new_user)			
			print(request.user.id, request.user)
			
			return render(request, "accounts/success.html")


	form =UserCreationForm()
	context = {"forms":form}
	return render(request, "accounts/home.html", context)

とにかくdjangoが準備したUserCreationFormにユーザーネームやらパスワードを入力したあとにUserCreationFormのインスタンスメソッドsave()すれば良い。create,create_userは使わなくて良い。
あとこれは想像だけれどもパスワードを登録するときには、文字列型の状態だと登録ができないのではないか?
パスワードを登録する際に$$$のような形で登録しないとうまく保存されないような気がする。入力したパスワードの文字列型からこの形に変換してくれる機能をUserCreationFormは有していると思われる。

forms.pyに使うlabelの働き

labelの働きがわからなかった。
htmlを学習した現在働きが同じだと思われる。まずhtmlの使い方を記述する。

<form>
     <label for="fullname">お名前</label>
     <input id="fullname" type="text" name="name">
     <label for="passwd">パスワード</label>
     <input id="passwd" type="password" name="password">
     <button type="submit"> ログイン</button>
</form>

htmlをこのように記述すると、入力欄(この場合は名前とパスワード欄)の直前にlabelタグで囲まれた単語が表示される。
htmlかdjangoのformかの違いはあれど、働きは同じ。フォーム欄に紐付いたラベルをつけることができる。



おそらくこれっぽい。記録しておく。
参考
Djangoで入力フィールドにプレースホルダ(placeholder)を設定する

hoge=forms.CharField(label = ' x')
このように設定してあげると、htmlではxと表示される。

話はそれるけれども、
CharField()の中でlabelとTextInput ,PasswordInputが独立している理由もhtmlを参考に考えると納得がいく。
label='PASSWORD'とPasswordInputはそれぞれタグを表しており、両者は併存関係である。
だからCharFieldの()内で並立して記述していると思われる。
labelはタグで挟むので=を使い、Inputタグはタグ内にidとかclassを書いたりする。それを表現するためにattr={}というスタイルを撮っていると考えれば覚えやすいのではないだろうか?

ユーザーログイン機能をdjangoプロジェクトに実装する/ユーザー認証の仕組み

ユーザーログイン機能をdjangoプロジェクトに実装する


  • 最初に主要ファイルにどのように書けばユーザーログイン実現するかを書く
  • 次にユーザー認証の仕組みを書く

ユーザーログイン実現の書き方

編集ファイルはこれらになる。
forms.py
views.py
urls.py
login_page.html

イメージはforms.pyにて入力フォームを規定して、それをviews.pyにcontextという形で反映させる。views.pyとlogin_page.htmlの関係性は普段と同じ通り。urls.pyも得に変わった処理もなくいつもどおりの書き方で良し。

forms.py

from django import forms

class LoginForm(forms.Form):
    username = forms.CharField()
    password = forms.CharField(widget=forms.PasswordInput)

はっきりしていないのはPasswordInputはTextInputとどう違うのか?
html上の仕組みから考えれば、ブラウザ上でパスワード入力時に文字隠しになる可能性が高い。
検証後この件については更新したい。

views.py

from .forms import LoginForm
from django.shortcuts import render,redirect
from django.contrib.auth import login,


def login_page(request):
    form = LoginForm()
    context = {"form" : form, }
    if form.is_valid():
        username = form.cleaned_data.get("username")
        password = form.cleaned_data.get("password")

        user = authenticate(username =username, password = password )
        if user is not None:
            login(request, user)
            redirect("home_page.html")
        else:
            print(error)
    return render(request, "login/page.html", context )


ユーザー認証の仕組みを書く


仕組みの肝であるauthenticateはなぜ必要なのか?

''認証情報のセットを検証するには authenticate() を利用してください。このメソッドは認証情報をキーワード引数として受け取ります。検証する対象はデフォルトでは username と password であり、その組み合わせを個々の 認証バックエンド に対して問い合わせ、認証バックエンドで認証情報が有効とされれば User オブジェクトを返します。もしいずれの認証バックエンドでも認証情報が有効と判定されなければ PermissionDenied が送出され、None が返されます。以下は実装例です:
from django.contrib.auth import authenticate
user = authenticate(username='john', password='secret')
if user is not None:
    # A backend authenticated the credentials
else:
    # No backend authenticated the credentials 

#django ドキュメントより

ドキュメントは、usernameとpasswordをauthenticate()に渡してくれれば、ログイン可能な(認証された)userを吐き出してくれるってこと。 
それは重要なlogin()の引数の1要素。login()は下のようにに使う。

login( request, user)

目的はログインすること。
そのためにはlogin(request, user)を実行する。
そしてその引数であるuserが必要。
このuserを作り出すのがauthenticate()。
authenticate()の引数はusername=フォームに入力されたusernameの値(value)とpassword=フォームに入力されたpasswordの値(value)
formに入力された値を取り出すのはis_valid(), cleaned_dataを用いる。

これらの相互関係がポイント。
コードはこの論理の逆に書いていけばログインが成立する。

formの扱い方 まとめ

フォームについて 

リンク先

forms.pyに使うlabelの働き
forms.py外で定めなければならないもの
formの入力データを返す方法(cleaned_data)



 

フォームにはforms.pyを使う方法とformのhtmlをテンプレートに挿入する方法がある。
①forms.pyについて記載する。

 

forms.pyの使いかたのイメージ
views.pyでお馴染みのrender(request,"hoge/hoge.html",context)を使う。contextにforms.pyの内容をぶち込む。forms.pyを作るのはフォームの内容は複雑だからforms.pyで作っておいて必要なぶち込み要素だけ呼び出すってイメージ。


手順
ディレクトリはアプリケーションで指定したところ。
そこにforms.pyを作成する。

forms.py は以下のようにクラス指定し入力フォームを要素を決めてあげる。

 

forms.py

from django import forms

class RegisterForm(forms.Form):

    user = forms.CharField()
    email = forms.EmailField()
    password = forms.CharField()

これで入力フォームができる。
これを記述するとinputタグとほぼ同じ役割があると思って良い。
inputタグの場合class指定、placeholder指定やname指定していたけど、それらはFieldの括弧内で指定することになる。
下に記述する。
 


参考までにinputタグと同じようにclassやplaceholderをどのようにすれば設定できるのかを書く。
ドキュメントにはこう書いてある。
”フォームフィールドは、HTML "ウィジェット” - ユーザーインターフェイスの装置の一つです - としてブラウザ内のユーザーに表されます。それぞれのフィールドタイプは、適切なデフォルトの Widget class を持っていますが、これらは必要に応じてオーバーライドできます。” 
https://docs.djangoproject.com/ja/2.1/topics/forms/#the-django-form-class

つまり何が言いたいかって言うと、()に何かを記すことは、ブラウザを使っているユーザに意図したとおりの見え方に設定することなのだ。

ここでは、フィールド括弧内の内容だけを書く。

widget=forms.TextInput(attrs={"class":"form-control","placehplder":"User Name","name":"user name",})

typeについてはここに含めてもいいと思うけど、ドキュメントは独立して書く方法があるとしている。
ウィジェット | Django documentation | Django


追記
widgetの種類はいっぱいある。これらについて一応仮説がある。
widget=forms.TextInput()の部分で、TextInputの他にEmailInput,Textareaの種類がある。
まずinputタグかtextareaタグかに分かれる。inputタグ系はTextInput,EmailInputである。
Textareaはtextareaタグだ。次にinputタグ系はそれぞれtypeをInput前に表現している。
だからinputタグ系を選んだら、自動的にバリエーション機能も持つことになる。



②formのhtmlをテンプレートに挿入する方法
forms.pyを用いた方法はrenderを使って記述する方法で、②の方法はテンプレートに挿入する方法なのでクラス別汎用ビューだろうがrenderを使っていようが使える方法。

まずhtmlを準備

<form method="POST" >
  <input class="form-control " type="text" placeholder="message to me" >
  <button type="submit">Submit</button>
</form>


これをテンプレートに挿入

{% include "hoge" %}


追記:forms.pyの書き方
forms.pyでforms.Formを継承してフォームを書く方法にはもう一つの方法がある。
参照先:
https://djangogirlsjapan.gitbooks.io/workshop_tutorialjp/content/django_forms/

従来の書き方を記すと

from django import forms

class RegisterForm(forms.Form):

    user = forms.CharField()
    email = forms.EmailField(widget=forms.EmailInput)
    password = forms.CharField()

こんな感じだ。ただmodels.pyのRegisterFormを利用するとこんな書き方で済ませることができる。

from django import forms
from hoge.models import Register
 
class RegisterForm(forms.Form):
    class Meta:
        model = Register 


次にviews.pyと表示されるhtml関係をテーマにする


views.py にて

from .forms import RegisterForm

def user_register(request) :
    
    form = RegisterForm(request.POST)
    context = {"form" : form }
return render(request, 'register.html', context) 

説明:request.POSTのデータを受け取ったformのオブジェクトを作成する。


そしてregister.htmlの{{ form }}を記載したところに入力フォームが表示されることになる。
イメージ的には下記のようになる。

<form method="POST">{% csrf_token %}
{{ form }}
<button >submit</button>

これでhtmlに反映されるようになる。
views.pyについてより実用的なコードに変換すると以下になる。

from .forms import RegisterForm

def user_register(request) :
    if request.method == POST:
        form = RegisterForm(request.POST)
        if form.is_valid():
            return HttpResponseRedirect('/thanks/')
   else:
         pass  
    context = {"form" : form }
    return render(request, 'register.html', context) 

速くコーディングするコツ

まずコピーアンドペーストを原則として、コピペができなければタイピングを行う。

macの操作方法を使いこなす。
画面移動:control + ← or →
文字移動:command + ← or →

Django ウェブアプリケーション内のPOSTされたデータを表示させる

必要なことはviews.pyにてdef と return の間に以下の内容を追加するだけで良い。

if request.method == "POST":
 print(request.POST)

これだけでターミナルに表示されるようになる。しかしながらこれだけではターミナルに入力されたデータがどのようなものだか分からないので、htmlまたはhtmlテンプレの<input> に以下を追加すると良い。name="hoge" これでhogeに何を入力したかわかるようになる。

追記:入力した内容だけをターミナルに表示させる方法
views.pyにて

def hoge(request):

    print(request.POST)
    print(request.POST.get("content"))

つまりget()を使うことで解決できる。

ウェブアプリケーションを作るときのイメージ

パーツの組み合わせを行っているだけ。

なんのパーツが必要か考えて、パーツの働きを設定して、パーツとパーツの接合面を設定する。

これだけな気がする。

 

django postgresqlの設定

概要 改正版

centos7にpostgresqlを入れてdjangoを動かす場合を想定している。
djangopostgresqlを使うためにdjangoのsettings.pyにpostgresqlのデータベースの諸情報を登録する手続きを取らなければならない。そしてそれは、

  • サーバにpostgresqlをインストールする
  • データベースクラスターやデータベースを作成する
  • postgresqlpythonで扱うためのモジュールpsycopg2等をインストール

といった下準備が追加的に必要なことを意味する。

postgresqlのデータベースに接続するには3つのステップを踏む。
参考:https://dba.stackexchange.com/questions/180209/postgresql-service-start-failed-on-cento

  1. postgresqlをインストールする
  2. データクラスター($PGDATA)を作成する
  3. サーバーを始動させる

このステップにdjangoでデプロイするための工程を加える。

1.postgresqlをインストールする

外部リポジトリを利用する理由

centos7にはpostgresqlが備え付けられているので、そのまま

sudo yum install postgresql

で、postgresqlをインストールしようと考えることもあろう。
残念ながらこの方法でpostgresqlを使うのは問題がある。問題はpostgresqlのバージョンだ。
試しにcentos7備え付けのpostgresqlをインストールし、バージョンを確認すると以下になる。

$ postgres --version

postgres (PostgreSQL) 9.2.24

django2.1からはpostgresql9.4以上を使うことを想定している。
参照:https://docs.djangoproject.com/ja/2.1/releases/2.1/#dropped-support-for-postgresql-9-3

これが備え付けのpostgresqlをインストールする問題点だ。そしてこの問題の避策としてpostgresql公式リポジトリを利用する。下記では公式リポジトリからインストールする方法を記録した。

postgreSQLをインストールする

postgeSQL公式のリポジトリを利用する。
https://yum.postgresql.org/

$ sudo yum install https://download.postgresql.org/pub/repos/yum/reporpms/EL-7-x86_64/pgdg-redhat-repo-latest.noarch.rpm

リポジトリにpostgresql11が加えられたかは以下のコマンドで確認する。

# yum info postgresql11-server

#結果
Loaded plugins: fastestmirror
Loading mirror speeds from cached hostfile
 * base: mirrors.cat.net
 * epel: ftp.jaist.ac.jp
 * extras: mirrors.cat.net
 * updates: mirrors.cat.net
Available Packages
Name        : postgresql11-server
Arch        : x86_64
Version     : 11.3
Release     : 1PGDG.rhel7
Size        : 4.7 M
Repo        : pgdg11/7/x86_64
Summary     : The programs needed to create and run a PostgreSQL server
URL         : https://www.postgresql.org/
License     : PostgreSQL
Description : PostgreSQL is an advanced Object-Relational database management system (DBMS).
            : The postgresql11-server package contains the programs needed to create
            : and run a PostgreSQL server, which will in turn allow you to create
            : and maintain PostgreSQL databases.
# 上記のように表示されたらdjango用のpostgresqlはインストールされました。

 

リポジトリをインストール後postgresqlをインストールする。今回はpostgresql11を利用する。
postgresql11-serverのインストールで依存するパッケージもインストールされる。

# yum install postgresql11-server
# yum install postgreql-serverにするとcentos7備え付けのpostgresqlをインストールすることになるので気をつけること

 

そうすると以下のような依存関係にあるものも一緒にインストールされる。

Installed:
  postgresql11-server.x86_64 0:11.3-1PGDG.rhel7                                                                      

Dependency Installed:
  libicu.x86_64 0:50.1.2-17.el7  postgresql11.x86_64 0:11.3-1PGDG.rhel7  postgresql11-libs.x86_64 0:11.3-1PGDG.rhel7 

2.データクラスター($PGDATA)を作成する

データクラスターを作成するためにはPostgreSQLの初期化する。初期化すると自動的にデータクラスターを作成される。
参考:https://www.postgresql.jp/document/10/html/creating-cluster.html
初期化するにはinitdbコマンドを入力する必要がある。しかしながらinitdbへのパスが通っていないので以下のようにしてinitdbコマンドを入力する。

# initdbの実行
# /usr/pgsql-11/bin/postgresql-11-setup initdb

Initializing database ... OK

インストールするとpostgresユーザが自動的に作成される。このpostgresユーザのパスワードを設定する。パスワードの設定はos(centos7)のユーザ切り替え用のパスワードの設定とpostgresqlに接続するためのパスワードの設定がある。

# osユーザ切り替えのためのパスワード設定

sudo passwd postgres

Changing password for user postgres.
New password: 
Retype new password: 
passwd: all authentication tokens updated successfully.

ちなみにpostgresql11の場合データベースクラスターは以下のパスに作成される。

/var/lib/pgsql/11/data

参考:https://qiita.com/zabutonzabuzabu/items/070a7f833bb321e46b0e

上記の手順について

postgresqlをインストールしたら、まず自分でinitdbコマンドを入力する必要があると考えていた。
しかし以下のドキュメントでは手動でinitdbコマンドを入力する必要はなく、最初のsystemctl start postgresql-11を入力したらデータベースクラスタの初期化(initdb)が行われる、と書いてある。これについてはまだ試していないので試し次第、またこの記事を再編集しようと思う。
https://lets.postgresql.jp/documents/tutorial/centos/2
djangoをデプロイするだけなら説明したように手動でinitdbをする方法で確実に行うことができる。

3.サーバーを始動させる

以下のコマンドで実行する

# systemctl start postgresql-11
# systemctl enable postgresql-11

ポートを開放する

# firewall-cmd --permanent --add-service=postgresql
# firewall-cmd --reload
# systemctl restart firewalld

ここまででpostgresqlのインストール、初期化、サービスの始動が完了した。
次に

  1. djangoに接続する用のデータベースを作成すること
  2. 作成したデータベースに認証させるユーザ設定を行うこと
  3. djangoのsettings.pyの設定をすること

を見ていく。

4.データベースを作成する

データベースを作成する。この時のデータベースはdjangoの仕様に合わせるための設定と自分が作ったプロジェクトに合うための設定(データベース名やユーザー名)を行う。
djangoの仕様に合わせた設定は以下の通りである。

  • client_encoding: 'UTF8'
  • default_transaction_isolation: 'read committed' by default, or the value set in the connection options (see below)
  • timezone: 'UTC' when USE_TZ is True, value of TIME_ZONE otherwise

参照:https://docs.djangoproject.com/ja/2.2/ref/databases/#optimizing-postgresql-s-configuration
下記ではALTER ROLEで設定しているが、postgresql.confでも設定することができるようだ。

# su postgres
psql -U postgres

データベースユーザを定める前に、postgresのパスワードを定める。

ALTER ROLE postgres WITH PASSWORD '設定したいpostgresのパスワード';

ここで定めておかないと、pg_hba.confでベーシック認証(md5)に切り替えるのでpostgresユーザーとしてデータベースに接続することができなくなるので注意すること。

データベースを以下のコマンドで作成し、次いでパスワードと一緒にユーザを作成する。

# データベースの作成
CREATE DATABASE [database名] ;
# ユーザを作成する
CREATE USER [ユーザ名] WITH PASSWORD '[パスワード]' ;
ALTER ROLE [ユーザ名] SET client_encoding TO 'utf8' ;

ALTER ROLE [ユーザ名] SET default_transaction_isolation TO 'read committed';

ALTER ROLE [ユーザ名] SET timezone TO 'Asia/Tokyo';

# このセット内容をデータベースに反映させるコマンドをが以下のもの。
GRANT ALL PRIVILEGES ON DATABASE [database名] TO [ユーザ名];
\q

ALTER ROLE [ユーザ名] SET client_encoding TO 'utf8' ;の関連内容
http://torajirousan.hatenadiary.jp/entry/2019/07/27/042306

5.django settings.pyを編集する

settings.pyの

    DATABASES = {
        'default': {
            'ENGINE':  'django.db.backends.postgresql', #新たに入力した項目         
            'NAME': '',  # データベース名
            'USER': '',  # ユーザ名
            'PASSWORD': '',  # password
            'HOST': 'localhost',  # DBがあるサーバのIPアドレスやホストを入力。空欄はローカルホスト
            'PORT': '5432',  # 新たに入力した項目(ポート番号を特に指定しなかったら''でも可)
            }
        }    

上記のNAMEにdatabase名を、USERにユーザ名を、PASSWORDにパスワードを記述する。
参考:https://docs.djangoproject.com/ja/2.2/intro/tutorial02/#database-setup

つぎにpostgresqlのユーザ認証の設定ファイルを編集する。

vi /var/lib/pgsql/11/data/pg_hba.conf
#認証方法をpeerからmd5に変更
local   all     all     md5
sudo systemctl restart postgresql-11
sudo systemctl status postgresql-11

これでmakemigrationsが通ればオッケイ。

python36 manage.py makemigrations    
python36 manage.py migrate

参考:https://qiita.com/zabutonzabuzabu/items/070a7f833bb321e46b0e

django startproject ディレクトリの影響 について

ディレクトリ構造について説明する。
src chiaki$ django-admin startproject hoge .
src chiaki$ django-admin startproject hoge
があり、両者の違いはdjangoを現在のディレクトリに備え付けるか否かの違いになる。前者は現在のディレクトリに備え付ける。だから

src--- hoge
      |_ manage.py

となるのに対し、後者は

src----hoge----hoge
                   |_manage.py

となる。なんとなくディレクトリの管理がおかしいなぁと思っていたのでこの点は解決した。