アプリケーションの基本骨格の作り方はだいたいわかってきたので、ちょっとデータベース検索の方を進めてみよう。
まずは先だって作ったアプリのデータベース(ユーザー管理)を流用して、保存されているデータを一覧で表示することをやってみる。
models.pyにデータベースの内容が規定されている。
class Role(db.Model): __tablename__ = 'roles' id = db.Column(db.Integer, primary_key=True) name = db.Column(db.String(64), unique=True) users = db.relationship('User', backref='role', lazy='dynamic') def __repr__(self): return '<Role %r>' % self.name class User(db.Model): __tablename__ = 'users' id = db.Column(db.Integer, primary_key=True) username = db.Column(db.String(64), unique=True, index=True) role_id = db.Column(db.Integer, db.ForeignKey('roles.id')) sex = db.Column(db.String(64)) pos = db.Column(db.String(64)) test = db.Column(db.Float) test2 = db.Column(db.Float) score = db.Column(db.Integer) def __repr__(self): return '<User %r>' % self.username
この場合2つのテーブルが用意されていて、一つはユーザーの登録、もう一つはユーザーの役割を割り振る表だ。
今回は後者は置いておいて前者だけをまず表示させてみる。
そのためにまずはview.pyを編集
from flask import render_template, session, redirect, url_for from flask_wtf import FlaskForm from wtforms import StringField, SubmitField from wtforms.validators import Required from app.models import User, Role from app import app, db, moment, manager class NameForm(FlaskForm): name = StringField('What is your name?', validators=[Required()]) submit = SubmitField('Submit') @app.errorhandler(404) def page_not_found(e): return render_template('404.html'), 404 @app.errorhandler(500) def internal_server_error(e): return render_template('500.html'), 500 ''' @app.route('/', methods=['GET', 'POST']) def index(): form = NameForm() if form.validate_on_submit(): user = User.query.filter_by(username=form.name.data).first() if user is None: user = User(username=form.name.data) db.session.add(user) session['known'] = False else: session['known'] = True session['name'] = form.name.data return redirect(url_for('index')) return render_template('index.html', form=form, name=session.get('name'), known=session.get('known', False)) ''' @app.route('/') def index(): user = User.query.order_by(User.id.asc()) return render_template("index.html", contents=user)
'''から’’’までは編集する前の部分なのでコメントアウトしておき、その下が新たに書いた部分。
テーブル定義Userから全部抽出してidで降順に並べてuserに入れ、userの中身をindex.htmlのcontentsのところに当てはめてレンダリングしましょう、という内容。
一方、templates/index.htmlは
{% extends "base.html" %} {% import "bootstrap/wtf.html" as wtf %} {% block title %}GID Database{% endblock %} {% block page_content %} <h1>Sample List</h1> <div class="table-responsive"> <table class="table table-striped"> <thread> <tr> <th>ID</th> <th>Username</th> <th>Sex</th> <th>Role_ID</th> <th>Score</th> <th>Position</th> <th>Test1</th> <th>Test2</th> </tr> </thread> <tbody> {% for samp in contents %} <tr> <td>{{ samp.id }}</td> <td>{{ samp.username }}</td> <td>{{ samp.sex }}</td> <td>{{ samp.role_id }}</td> <td>{{ samp.score }}</td> <td>{{ samp.pos }}</td> <td>{{ samp.test }}</td> <td>{{ samp.test2 }}</td> </tr> {% else %} <td>no entry exist!</td> {% endfor %} </tbody> </table> </div> </div> {% endblock %}
base.htmlを拡張して当てはめることにしてbase.htmlの{% block page_content %}{% endblock %}部分にこちらの{% block page_content %}から{% endblock %}までを入れ込む。その内容はまあ普通にテーブルタグで組んだHTML書式で、
{% for samp in contents %} {{ samp.xxx }} {% else %} {% endfor %}
のところでview.pyで定義したcontents(つまりデータベースのUser表から読み取った項目user)から1行ずつ読み出してsampに入れ、それを項目ごとに分けて所定のカラムに配置、ということをしている。
つづいて検索。view.pyのルーティングのところをちょっといじる。
@app.route('/', methods=['GET', 'POST']) def index(): form = NameForm() user = User.query.filter_by(username=form.name.data) return render_template('index.html', form=form, contents=user)
そしてindex.htmlで先程消してしまった
{{ wtf.quick_form(form) }}
を復活させる。
それだけでとりあえずは名前で検索できるようになる。
本当はredirectとuser sessionを使いたいのだが、まだスキルが足りない。
検索窓の文言もこれじゃ変だわな。
必要ないかもしれないけど日本語もちゃんと通る。検索窓を上に配置してみた。次は複数の検索条件を同時もしくは順番に処理して抽出することを目指す。AND OR NOTも使えるようにしたいところ。