[Python]とにかくわかりやすく！Djangoでアプリ開発！ーその６ー

#前回の記事

[[Python]とにかくわかりやすく！Djangoでアプリ開発！ーその5ー](
https://qiita.com/hiroyuki_mrp/items/344c3b3ce44564dad3a4)

#本記事の目的
python初心者の方が、本記事を見たあとに、一人でアプリ開発できることを目的にしております。
※インストールや開発環境については記載しません

#環境
macOSX　Sierra
python3.7
django 2.1.5

前回まで
プロジェクトを立ち上げ(startproject)
→アプリの作成(startapp)
→view.pyを変更してレスポンスを書く
→urls.pyを修正する
→アプリの登録する
→index.html作る
→views.pyを直す
→htmlに変数入れる
→views.pyを直す
→複数ページ作るためにリンクつける
→views.pyを直す
→cssで装飾できるようにする
→htmlでフォームを作る
→views.pyを直す
→urls.pyを修正する
→やっぱりFormクラスでフォームを作る
→views.pyを直す
→index.html直す
→Viewクラスでview.pyをスッキリさせる
→Fieldをいじってみる
→models.pyでテーブルを定義してみる
→管理者を作成する、登録する

とここまででした。

ここからはDBとのアプリとの連携についてを記載していきます。

#その前にモデル定義を変更

わかりやすくするためにモデルを修正したいと思います。
今までのTourokuクラスを修正します。

```models.py
from django.db import models

class Touroku(models.Model):

    date = models.DateField()
    name = models.CharField(max_length=30)
    breakfast = models.BooleanField()
    lunch = models.BooleanField()
    dinner = models.BooleanField()
    eatout = models.BooleanField()
    drinking = models.BooleanField()
    workout = models.BooleanField()
    stretch = models.BooleanField()
    studying = models.BooleanField()
    awaketime = models.TimeField()
    asleeptime = models.TimeField()
    kenkobody = models.CharField(max_length=30)
    workcond = models.CharField(max_length=30)

    def __str__(self):
        return '<ID:'+str(self.id)+'>  名前:'+self.name
```

作り直しているのでお決まりのマイグレートを行います。

```
$ python manage.py makemaigrations
$ python manage.py migrate
```

問題ないと思いますが、admin.pyが以下になっていることを確認します。

```admin.py
from django.contrib import admin
from .models import Touroku

admin.site.register(Touroku)
```

ログインしてテストデータ登録を登録しておきます。３つくらいあるといいかと。（別に幾つでもいいです）

#レコードを表示できるようにする

Tourokusの全レコードを取得できるようにします。表示できるような処理にするのでviews.pyを修正します。
最初にmodelsからTourokuをインポートしておきます。今までのTemplateviewは一旦無くします。
index関数の中身は、とても簡単で、dataという変数の中にTouroku.objects.all()とすることでDBのデータ全てを代入します。
モデルクラスを使っているわけですが、objectsという属性が用意されており、さらにメソッドとしてall()を使うことで、全てのレコードをモデルのインスタンスにしてまとめて呼び出しています。

```views.py
from django.shortcuts import render
from django.http import HttpResponse
from .models import Touroku

def index(request):
    data = Touroku.objects.all()#ここ
    params = {
        'title':'生活データ',
        'msg':'all records',
        'data':data,#ここ
    }
    return render(request,'kenko/index.html', params)
```
処理を変えたので、今度は表示そのものを修正します。
<table>タグを用意して、その中に\<tr>と\<th>で表のカラムを用意します。
そのあとは{% for item in data %}...{% endfor %}というfor文で纏めて取り出したデータを一つずつ取り出し、itemの中の情報を一つずつ{{item.name}}のように取り出しを行います。
Booleanのものに関しては、それぞれ分岐した文言を埋め込んでいます。

```index.html
{% load static %}
<!doctype html>
<html lang="ja">
    <head>
        <meta charset="utf-8">
        <title>{{title}}</title>
        <link rel="stylesheet" type="text/css"
        href="{% static 'kenko/css/style.css' %}"/>
    </head>
    <body>
        <h1>{{title}}</h1>
        <p>{{msg|safe}}</p>　　　<!--ここから-->
        <table>
            <tr>
                    <th>no</th>
                    <th>日付</th> 
                    <th>名前</th> 
                    <th>朝食</th> 
                    <th>昼食</th> 
                    <th>夕食</th> 
                    <th>外食</th> 
                    <th>飲酒</th> 
                    <th>運動</th> 
                    <th>ストレッチ</th> 
                    <th>勉強</th> 
                    <th>起床時間</th> 
                    <th>就寝時間</th> 
                    <th>健康</th> 
                    <th>仕事の調子</th> 
            </tr>
            {%for item in data %}
            <tr>
                    <td>{{item.id}}</td> 
                    <td>{{item.date}}</td> 
                    <td>{{item.name}}</td> 
                    <td>{% if item.bf == False %}No{% endif %} 
                        {% if item.bf == True %}Yes{% endif %}</td> 
                    <td>{% if item.lunch == False %}No{% endif %} 
                        {% if item.lunch == True %}Yes{% endif %}</td> 
                    <td>{% if item.dinner == False %}No{% endif %} 
                        {% if item.dinner == True %}Yes{% endif %}</td> 
                    <td>{% if item.eatout == False %}No{% endif %} 
                        {% if item.eatout == True %}Yes{% endif %}</td> 
                    <td>{% if item.drinking == False %}No{% endif %} 
                        {% if item.drinking == True %}Yes{% endif %}</td> 
                    <td>{% if item.workout == False %}No{% endif %} 
                        {% if item.workout == True %}Yes{% endif %}</td> 
                    <td>{% if item.stretch == False %}No{% endif %}
                        {% if item.stretch == True %}Yes{% endif %}</td> 
                    <td>{% if item.studying == False %}No{% endif %}
                        {% if item.studying == True %}Yes{% endif %}</td> 
                    <td>{{item.awaketime}}</td> 
                    <td>{{item.asleeptime}}</td> 
                    <td>{{item.kenkobody}}</td> 
                    <td>{{item.workcond}}</td> 

            </tr>
            {% endfor %}<!--ここまで-->
        </table>
    </body>
</html>
```
urls.pyは以下のように修正をします。viewを使わなくなったので元に戻した感じです。

```urls.py
from django.urls import path
from . import views

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

cssは適当につけておきます。

```css
table {
    margin:10px;
    font-size:14pt;
}

table tr th {
    background-color: rgb(43, 139, 204);
    color:black;
    padding:2px 10px;
    border-width:2px;
}

table tr td {
    background-color: rgb(43, 139, 204);
    color:black;
    padding:2px 10px;
    border-width:2px;
}
```

#検索機能を実装

せっかくなので検索機能を実装します。
今回はIDでデータを検索できるようにします。
それようのフォームを設定する必要があるので、forms.pyを修正します。

```forms.py
from django import forms

class IdKensaku(forms.Form):
    id = forms.IntegerField(label = "ID")
```

Formをhtmlに実装します。
POSTで投げるようにするにmethodで指定をします。
※以下bodyの開始からtableの冒頭までの部分

```index.html
・
・
・
<body>
        <h1>{{title}}</h1>
        <p>{{msg|safe}}</p>
        <table>
            <form aciton = "{%url 'index' % }" method = "POST">
                {% csrf_token %}
                {{form.as_table}}
            <tr><td></td><td><input type = "submit" value = "検索"></td></tr>
            </form>
        </table>
        <hr>
        <table>
            <tr>
                    <th>id</th>
・
・
・
```

埋め込みができたので、表示できるような処理にするためviews.pyを修正。
formsからインポートしてます。
POSTデータからidを受け取り、numberに代入を行なって、objects.get()の引数に代入を行なっています。先ほどはobjects.all(）でしたが、getにすることで特定のものだけを抽出します。allと違うのは、getではモデルのインスタンスを一つだけ取り出しているので、params['data'] = [item]で代入をしています。

```views.py
from django.shortcuts import render
from django.http import HttpResponse
from .models import Touroku
from .forms import IdKensaku

def index(request):

    params = {
        'title':'生活データ',
        'msg':'all records',
        'form':IdKensaku(),
        'data':[],
    }

    if (request.method =='POST'):
        number = request.POST['id']
        item = Touroku.objects.get(id = number)
        params['data'] = [item]
        params['form'] = IdKensaku(request.POST)
    else:
        params['data'] = Touroku.objects.all()
    return render(request, 'kenko/index.html', params)
```

ここまでやったら、
$ python manage.py runserverをしてhttp://127.0.0.1:8000/app1/
にアクセスしてみましょう。
やってみましょう。このような感じになっていたらOKです。※実際にはyes/noが付いてたらOKです。
<img width="618" alt="スクリーンショット 2019-03-10 19.48.21.png" src="https://qiita-image-store.s3.amazonaws.com/0/241505/f156a8b9-6fa2-a89c-58eb-d719ac9fb3c3.png">

#メソッドチェーン

特段ここでの用途はないですが、
objects属性でメソッドチェーンを使えば表示するものを制限できます。先ほどのgetのように、valuesというものを使えば、特定の要素だけ取り出すこともできます。また詳細は割愛しますが、メソッドにはcountやfirstなどの便利なものも用意されています。

```views.py
from django.shortcuts import render
from django.http import HttpResponse
from .models import Touroku
from .forms import KenkoForm

def index(request):

    params = {
        'title':'生活データ',
        'msg':'all records',
        'form':KenkoForm(),
        'data':[],
    }

    if (request.method =='POST'):
        nametxt = request.POST['name']
        item = Touroku.objects.get(name = nametxt)
        params['data'] = [item]
        params['form'] = KenkoForm(request.POST)
    else:
        params['data'] = Touroku.objects.values("id","name")#ここ
    return render(request, 'kenko/index.html', params)
```

#この記事はここまで

続きはこちら→[[Python]とにかくわかりやすく！Djangoでアプリ開発！ーその７ー](https://qiita.com/hiroyuki_mrp/items/3ef6aeba5e342d4fe672)