[Django]モデルのカスタマイズ

### モデルのリストを調査
/hello/views.py

from django.shortcuts import render
from django.http import HttpResponse
from .models import Friend

def index(request):
	params['data'] = Friend.objects.all()
	params = {
		'title': 'Hello',
		'data': data,
	}		
	return render(request, 'hello/index.html', params)

/hello/templates/hello/index.html

from django.shortcuts import render
from django.http import HttpResponse
from .models import Friend

def index(request):
	data = Friend.objects.all()
	params = {
		'title': 'Hello',
		'data': data,
	}		
	return render(request, 'hello/index.html', params)

– .objects.all()で取り出していたのはQuerySetというインスタンスだということがわかる
– QuerySetには__str__も含む

### valuesメソッド
– .objects.values()で辞書でデータを取り出すことができる
/hello/views.py

def index(request):
	data = Friend.objects.values()
	params = {
		'title': 'Hello',
		'data': data,
	}		
	return render(request, 'hello/index.html', params)

– 特定の項目を指定

def index(request):
	data = Friend.objects.values('id', 'name')
	params = {
		'title': 'Hello',
		'data': data,
	}		
	return render(request, 'hello/index.html', params)

– リストとして取り出す

data = Friend.objects.all().values_list('id', 'name','age')

– first最初、last最後、countレコード数

def index(request):
	num = Friend.objects.all().count()
	first = Friend.objects.all().first()
	last = Friend.objects.all().last()
	data = [num, first, last]
	params = {
		'title': 'Hello',
		'data': data,
	}		
	return render(request, 'hello/index.html', params)

– QuerySetのカスタマイズ

from django.shortcuts import render
from django.http import HttpResponse
from .models import Friend
from django.db.models import QuerySet

def __new_str__(self):
	result = ''
	for item in self:
		result += '<tr>'
		for k in item:
			result += '<td>' + str(k) + '=' + str(item[k]) + '</td>'
		result += '</tr>'
	return result

QuerySet.__str__ = __new_str__

def index(request):
	data = Friend.objects.all().values('id', 'name', 'age')
	params = {
		'title': 'Hello',
		'data': data,
	}		
	return render(request, 'hello/index.html', params)
<body class="container">
	<h1 class="display-4 text-primary">{{title}}</h1>
	<table class="table">
		{{data|safe}}
	</table>
</body>

reverseなどもviews.pyで整形すれば良いのですね、少しイメージが湧いてきました。

[Django]指定IDのレコードを取得

### 特定のIDのみ取り出す
/hello/forms.py

from django import forms

class HelloForm(forms.Form):
	id = forms.IntegerField(label='ID')

/hello/templates/hello/index.html

<body class="container">
	<h1 class="display-4 text-primary">{{title}}</h1>
	<p class="h5 mt-4">{{message|safe}}</p>
	<form action="{% url 'index' %}" method="post">
		{% csrf_token %}
		{{ form}}
		<input type="submit" value="click">
	</form>
	<hr>
	<table class="table">
		<tr>
			<th>ID</th>
			<th>NAME</th>
			<th>GENDER</th>
			<th>MAIL</th>
			<th>AGE</th>
			<th>BIRTHDAY</th>
		</tr>
	{% for item in data %}
		<tr>
			<td>{{item.id}}</td>
			<td>{{item.name}}</td>
			<td>{% if item.gender == False %} male{% endif%}
				{% if item.gender == True %} female{% endif%}</td>
			<td>{{item.mail}}</td>
			<td>{{item.age}}</td>
			<td>{{item.birthday}}</td>
		</tr>
	{% endfor %}
	</table>
</body>

– Friend.objects.get(id=num)でレコードを一つ取り出す
– Managerクラスが取り出している
/hello/views.py

from django.shortcuts import render
from django.http import HttpResponse
from .models import Friend
from .forms import HelloForm

def index(request):
	params = {
		'title': 'Hello',
		'message': 'all friends.',
		'form': HelloForm(),
		'data': [],
	}
	if(request.method == 'POST'):
		num=request.POST['id']
		item=Friend.objects.get(id=num)
		params['data'] = [item]
		params['form'] = HelloForm(request.POST)
	else:
		params['data'] = Friend.objects.all()
	return render(request, 'hello/index.html', params)

views.pyの関数がMVCのコントローラみたいな役割をしてますね。

[Django]レコードの取得

### レコードの表示
– data = Friend.objects.all() で取り出す
/hello/views.py

from django.shortcuts import render
from django.http import HttpResponse
from .models import Friend

def index(request):
	data = Friend.objects.all()
	params = {
		'title': 'Hello',
		'message': 'all friends.',
		'data': data,
	}
	return render(request, 'hello/index.html', params)

– {% for item in data %}{% endfor %}で繰り返し処理
– {% if %}{% endif %}で条件分岐
/hello/templates/hello/index.html

<body class="container">
	<h1 class="display-4 text-primary">{{title}}</h1>
	<p class="h5 mt-4">{{message|safe}}</p>
	<table class="table">
		<tr>
			<th>ID</th>
			<th>NAME</th>
			<th>GENDER</th>
			<th>MAIL</th>
			<th>AGE</th>
			<th>BIRTHDAY</th>
		</tr>
	{% for item in data %}
		<tr>
			<td>{{item.id}}</td>
			<td>{{item.name}}</td>
			<td>{% if item.gender == False %} male{% endif%}
				{% if item.gender == True %} female{% endif%}</td>
			<td>{{item.mail}}</td>
			<td>{{item.age}}</td>
			<td>{{item.birthday}}</td>
		</tr>
	{% endfor %}
	</table>
</body>

/hello/urls.py

from django.urls import path
from . import views

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

おおお、いいですね。MVCを触ってる感が出てきました。

[Django]データベースの管理ツール

Djangoにはデータベースの管理ツールが用意されていて、それを使ってWeb上でテーブルなどの編集が行える

### 管理者の作成
$ python manage.py createsuperuser
Username (leave blank to use ‘vagrant’): admin
Email address: ****@gmail.com
Password:
Password (again):
Superuser created successfully.

### モデルを管理ツールで利用できるようにする
– アプリケーションのadmin.pyで編集する
/hello/admin.py

from django.contrib import admin
from .models import Friend

admin.site.register(Friend)

### adminログイン
http://192.168.33.10:8000/admin


– AUTHENTICATION AND AUTHORIZATIONに「Groups」「Users」モデルが用意されている
– 下がmigrationで作成したテーブル

### 管理ツールからレコードの作成

### 利用者の管理ページ
add userから追加する

まあ、便利といえば便利

[Django]データベースの初期設定

Djangoで使えるデータベース: MySQL, PostgreSQL, SQLite
Djangoはプロジェクトにスクリプトを書くと、テーブルを自動生成する

### データベースの設定
– プロジェクトフォルダのsettings.pyを開く

DATABASES = {
    'default': {
        'ENGINE': 'django.db.backends.sqlite3',
        'NAME': os.path.join(BASE_DIR, 'db.sqlite3'),
    }
}

– ENGINE: アクセスに使われるプログラム名
– NAME: データベース名 SQLiteの場合、パスを設定する

– mysqlの場合

DATABASES = {
    'default': {
        'ENGINE': 'django.db.backends.mysql',
        'NAME': 'databasename',
        'USER': 'root',
        'PASSWORD': 'password',
        'HOST': 'localhost',
        'PORT': '3306',
    }
}

– PostgreSQLの場合

DATABASES = {
    'default': {
        'ENGINE': 'django.db.backends.postgresql',
        'NAME': 'databasename',
        'USER': 'root',
        'PASSWORD': 'password',
        'HOST': 'localhost',
        'PORT': '5432',
    }
}

### モデルの作成
– アプリケーションのmodels.pyを開く
/hello/models.py

from django.db import models

# Create your models here.

モデルクラスの作成
– 書き方はFormクラスとほぼ同じ
– django.db.modelsにあるModelクラスを継承している
– def __str__(self)はテキストの内容を返すもの

from django.db import models

class Friend(models.Model):
	name = models.CharField(max_length=100)
	mail = models.EmailField(max_length=200)
	gender = models.BooleanField()
	age = models.IntegerField(default=0)
	birthday = models.DateField()

	def __str__(self):
		return '<Friend:id=' + str(self.id) + ', ' + self.name + '(' + self.age + ')>'

### マイグレーションファイルの作成
$ python manage.py makemigrations helloMigrations for ‘hello’:
hello/migrations/0001_initial.py
– Create model Friend

### マイグレーションの実行
$ python manage.py migrate

作成されたmigrantionファイル
/hello/migrations/0001_initial.py

from django.db import migrations, models


class Migration(migrations.Migration):

    initial = True

    dependencies = [
    ]

    operations = [
        migrations.CreateModel(
            name='Friend',
            fields=[
                ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
                ('name', models.CharField(max_length=100)),
                ('mail', models.EmailField(max_length=200)),
                ('gender', models.BooleanField()),
                ('age', models.IntegerField(default=0)),
                ('birthday', models.DateField()),
            ],
        ),
    ]

– Migrationクラスはdjango.db.migraitonsにあるクラス
– operationsが実行するクラス