setoya-blog

システム開発技術、データ分析関連でお勉強したことや、山奥生活を綴る、テンション低めなブログです。

Google App Engine上でのdjango nonrelを使ったデータの永続化

2011-11-03 - setoyama日記で、Google App Engineの開発環境上にdjango nonrelのアプリ環境を作った。

今日は、djangoでの開発の仕方に従って、DB(といっても実際はNoSQLなDB)にエンティティのデータを保存するところまでやる。

データを保存するためにユーザーが入力する画面は今日は作らず、djangoの管理UIであるAdminSiteを使う。AdminSiteはいわゆるマスタメンテツールである。AdminSiteの機能は、かなり現場でもまれて作られたものらしく、実用に耐えられると評判を得ているそうだ。

全体の流れとしては、以下の感じ

  1. djangoプロジェクト内にアプリを作成
  2. アプリ内にModelの定義
  3. djangoプロジェクトのsettings.pyの修正
  4. djangoのコマンドを使って、Modelの情報をDBと同期
  5. urls.pyを修正してルーティングの設定

1. djangoプロジェクト内にアプリを作成

前回作ったアプリのルートフォルダは、実は、djangoでいうところのプロジェクトという単位らしい。

実際は、そのプロジェクト内にアプリケーションという単位でサブディレクトリを作り、そこにWebアプリケーションを作成していく。

今回作ろうとしているアプリケーションは、実はWebページはなく、サーバ側はWebサービスだけあればよい、というもの。

その場合もdjangoプロジェクトの下にアプリケーションを作るのは変わらないと思われるので、以下のようにdjangoのコマンドを入力して、アプリケーションを作成した。
このコマンドを入力する際は、manange.pyが配置されているプロジェクトのルートフォルダに移動しておく必要がある。

> python manage.py startapp nicarest

最後のnicarestはアプリケーション名。意味は非公開。

2. アプリ内にModelの定義

さっきのコマンドで、プロジェクトルートディレクトリの下にnicarestディレクトリが作成され、さらに以下のファイルが配置される。

  • __init__.py
  • models.py
  • tests.py
  • views.py


このうち、今回使うのは、models.py。その他の説明は省略します。
models.pyには、DBに保存するエンティティの定義を記載する模様。
複数ある場合も、複数のクラスを定義していく。

今回のアプリはワインの情報をGoogle App Engine上に保存したいので、以下のようにした。

from django.db import models

# Create your models here.
class Wine(models.Model):
    name = models.CharField(max_length=200)
    producer = models.CharField(max_length=200)
    varietals = models.CharField(max_length=200)
    vintage = models.IntegerField(max_length=4)
    rating = models.IntegerField(max_length=3)
    region = models.CharField(max_length=200)
    country = models.CharField(max_length=200)
    alcohol = models.IntegerField(max_length=3)

ついでに、管理UIでこのモデルを編集するために、以下の設定ファイルをmodels.pyと同じフォルダに作成して、中身を記載しておく。

  • admin.py
from django.contrib import admin
from models import Wine

class WineOptions(admin.ModelAdmin):
    pass

admin.site.register(Wine, WineOptions)

3. djangoプロジェクトのsettings.pyの修正

プロジェクトのルートディレクトリにあるsettings.pyにはDBとの接続設定やプロジェクトで使用するアプリケーションの設定を行う。

今回の場合、自分で作ったnicarestと管理UI用のアプリケーションを登録するために、INSTALLED_APPSのところを以下のように修正する。

INSTALLED_APPS = (
    'django.contrib.admin',
    'django.contrib.contenttypes',
    'django.contrib.auth',
    'django.contrib.sessions',
    'djangotoolbox',
    'autoload',
    'dbindexer',

    # add original app info
    'nicarest',

    # djangoappengine should come last, so it can override a few manage.py commands
    'djangoappengine',
)

冒頭のdjango.contrib.adminのところが、管理UIアプリケーションを使用するための設定で、途中のnicarestのところが、今回追加したアプリを使うための設定。

4. djangoのコマンドを使って、Modelの情報をDBと同期

この状態で以下のdjangoのコマンドを使うと、プロジェクト内の全アプリケーションのmodels.pyの情報が自動的に確認され、DBにテーブルが作られる。django nonrel では実際にはテーブルが作られる訳ではないと思うが、アプリケーション開発者にはバックエンドがRDBMSのように見えるようになっている。

> python manage.py syncdb

ちなみに、管理UIアプリケーションを使うための設定をしているので、このコマンドを実行するとき管理UIにログインするためのスーパーユーザーを作るか確認される。適当にユーザー名とかパスワードを入力して作っておく。

5. urls.pyを修正してルーティングの設定

urls.pyは、いわゆるルーティングの設定をするためのファイルで、Railsと似たような感じでURLに対する処理を指定する。

設定した内容としては、管理UI用のURLを追加して、それに対する処理を指定する代わりに、管理UI用アプリケーションディレクトリにあるurls.pyの設定情報を参照するようにする。
今回は、プロジェクトルートディレクトリのurls.pyを直接変更するが、アプリケーションごとにurls.pyを作って、それを参照させることもできるようだ。

  • urls.py
from django.conf.urls.defaults import *

from django.contrib import admin
admin.autodiscover()

handler500 = 'djangotoolbox.errorviews.server_error'

urlpatterns = patterns('',
    ('^_ah/warmup$', 'djangoappengine.views.warmup'),
    ('^$', 'django.views.generic.simple.direct_to_template',
     {'template': 'home.html'}),
    (r'^admin/', include(admin.site.urls)),
)

最後のadminのルーティングの設定のところで、admin.site.urlsを引用するために、ファイルの冒頭でにdjango.contribパッケージのadminモジュールを読み込んでおく。さらにadmin.autodiscober()を呼び出すのだけど、これが何を意味するのかは調べてないので不明。


以上の設定を行って、ローカルのサーバでhttp://localhost:8000/admin/(mange.pyの起動オプションによってポート番号などは変わる)などでアクセスすると管理画面にログインし、Wine情報を管理者として追加できる。

http://cdn-ak.f.st-hatena.com/images/fotolife/s/sessan/20111105/20111105224413_original.png:image:w550

ログインして、Wineを編集する画面はこんな感じ。