モブプロだった人のブログ

モブプログラミングに魅了されたエンジニアのブログ

Flask + Flask-SQLAlchemy のチュートリアルを日本語で (Relationships 編)

チュートリアル関連記事

はじめに

今回は、既存の Model(User) に Relationships を追加してみたいと思います。

本格的にやるには、もっと色々考慮するポイントがありますが、まずはざっくりと Relationships を追加してみます。

追加する Model ですが、ユーザごとの投稿記事(Post)のものです。

各ファイルの修正

Python ファイル修正

hello.py ファイルを以下のように修正します。

# 〜〜省略〜〜

class User(db.Model):
    id = db.Column(db.Integer, primary_key=True)
    username = db.Column(db.String(80), unique=True)
    posts = db.relationship('Post', backref='user', lazy=True) # 複数の Post への紐付け

    def __init__(self, username, posts=[]):
        self.username = username
        self.posts = posts # ユーザ追加時は基本的に空だと思いますが、念のため追加できるようにしておく

# Post クラスを追加
class Post(db.Model):
    id = db.Column(db.Integer, primary_key=True)
    title = db.Column(db.String(120), nullable=False)
    body = db.Column(db.Text, nullable=False)
    user_id = db.Column(db.Integer, db.ForeignKey('user.id'), nullable=False) # 一人の User への紐付け

    def __init__(self, title, body, user_id):
        self.title = title
        self.body = body
        self.user_id = user_id

    def __str__(self):
        return self.title

# 〜〜省略〜〜

テンプレートファイル修正

templates/top.html ファイルを以下のように修正します。

<!-- 省略 -->

  <table class="table">
    <thead>
      <tr>
        <th>ID</th>
        <th>名前</th>
        <th>投稿</th> <!-- 項目追加 -->
        <th>詳細</th>
      </tr>
    </thead>
    <tbody>
      {% for user in user_list %}
      <tr>
        <td>{{ user.id }}</td>
        <td>{{ user.username }}</td>
        <td>{{ user.posts|join(', ') }}</td> <!-- 投稿のタイトルをカンマ区切りで表示 -->
        <td>
          <a class="btn btn-success" href="{{ url_for('show_user', user_id=user.id) }}">
            <span class="glyphicon glyphicon-search" aria-hidden="true"></span> 詳細
          </a>
      </td>
      </tr>
      {% endfor %}
    </tbody>
  </table>

<!-- 省略 -->

動作確認前のデータ準備

Python インタプリタを起動し、以下を実行します。

# 色々 import
from hello import db, User, Post

# 一旦データベースを作り直す
db.drop_all()
db.create_all()

# admin ユーザを再作成
user = User('admin')
db.session.add(user)
db.session.commit()

# admin ユーザの投稿を2件作成
post1 = Post('title1', 'body1', user.id)
post2 = Post('title2', 'body2', user.id)
db.session.add(post1)
db.session.add(post2)
db.session.commit()

動作確認

トップページにアクセスすると・・・、

f:id:kaorr_mob:20180121214022p:plain

投稿したタイトルがうまく表示されていますね!

おわりに

今回は、本当にざっくりと Relationships を追加してみました。

また、データベースをばっさりと再作成していますが、本当は Flask-Migrate とか使うと良いと思います。が、説明に時間が掛かりそうなので、今回はばっさりといきました。

次回は、投稿データをどんな感じに表示するのか、どんな感じに変更、削除するのかを考えながら進めていきたいと思います。

ブログのアクセス数が急に増えてビックリした話

先日、アクセス解析画面を見たら、アクセス数が急に増えていてビックリしました・・・。

f:id:kaorr_mob:20180120230736p:plain

普段は 1 日で 20 〜 30 あたりをフラフラしているのですが、この日は 100 近い数値に到達しています。

一体何があったんだ!?

と思い、念のために入れておいた Google アナリティクスを見たところ、どうやら「Flask チュートリアル」の記事がやけにアクセスされていたようです。

いやはや、ありがたい話ですね、はい。

最近、Django に力を入れていて Flask の方は放置気味なのですが、また Flask 関連の記事でも書こうかなぁという気分になりました。

Python の Type Hints を今更ながら勉強してみる

最近、開発環境をより便利にするために色々調査していて、今更ながら Type Hints が気になってきたので勉強してみることにしました。

Type Hints とは Python 3.5 から導入されたものです。

業務で扱っている Python が 2 系のため、そもそも対象外と考えて今まであまり意識したことがなかったのですが、2 系でも対応できるような書き方があったんですね。

んで、PyCharm などの IDE を使っているとそれらを自動的に良い感じにやってくれることが分かり、

こりゃキャッチアップしとかにゃマズイ!

という感じです。

で、実際にコードを書いて試してみたのですが、

def get_full_name(first_name, last_name):
    # type: (str, str) -> str
    return first_name + ' ' + last_name


if __name__ == '__main__':
    full_name = get_full_name('Stevie', 'Wonder')

ここまで書いて、その後に full_name. と打つと、

f:id:kaorr_mob:20180119225515p:plain

すんばらしいですね。

ぜひ、今後は積極的に使っていきたいと思います。

Python で a == 1 and a == 2 and a == 3 が True になるやつ、の補足

先日の記事を見たチームの人から、

わけわからん!

と指摘を受けてしまったので、少し補足します。

先日の記事とは↓のことです。

Python で a == 2 and a > 3 and a < 4 を True にしてみる

コードで見た方が分かりやすいと思うので、先日とは違う感じで書いてみました。

class A:
    def __init__(self, start):
        self.number = start

    def __eq__(self, target):
        print(f'{self.number} == {target}')
        return True

    def __gt__(self, target):
        print(f'{self.number} > {target}')
        return True

    def __lt__(self, target):
        print(f'{self.number} < {target}')
        return True


a = A(1)

if a == 2 and a > 3 and a < 4:
    print('GOOD!')

# 1 == 2
# 1 > 3
# 1 < 4
# GOOD!

以上です。

はい、補足とか言いながら全然補足してないですね、あはは。

Python で a == 1 and a == 2 and a == 3 が True になるやつ

Twitter を眺めていたら、何やら面白そうな記事があったので、Python で真似てみることにします。

class A:
    def __init__(self, start):
        self.number = start

    def __eq__(self, target):
        if self.number != target:
            return False

        self.number += 1
        return True


a = A(1)

if a == 1 and a == 2 and a == 3:
    print('GOOD!')

うん、サクッとやってみましたが、なかなか面白いですね。

(実用性があるのかはよく分かりませんが・・・!)

こういう小さいネタを数多く重ねていくと、知らぬ間に言語仕様に詳しくなったり・・・しないか。