LoginSignup
3
6

More than 5 years have passed since last update.

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

Last updated at Posted at 2019-03-10

前回の記事

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

本記事の目的

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)

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

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

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)

処理を変えたので、今度は表示そのものを修正します。

タグを用意して、その中に<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は適当につけておきます。

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です。
スクリーンショット 2019-03-10 19.48.21.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でアプリ開発!ーその7ー

3
6
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
3
6