Djangoメモ(5) : 対話型シェルでAPIを使ってみる
A Complete Beginner's Guide to Djangoのチュートリアルを参考にDjango が提供する APIを使ってみる。
対話型シェルの起動
前回まででモデルの作成は完了しているのでAPIでオブジェクトを作成してみる。 まずは下記コマンドで対話型シェルを起動する。
$ python manage.py shell
ドキュメントによるとpython manage.py shell
と単なるpython
コマンドとの違いは下記とのこと。
なぜ単なる “python” コマンドではなく上記のコマンドを使うかというと、 manage.py が DJANGO_SETTINGS_MODULE 環境変数を設定してくれるからです。これにより、 Django に mysite/settings.py ファイルへの import パスが与えられます。
確かに単なるpython
コマンドでモデルをインポートしようとすると失敗してしまう。
>>> from boards.models import Board ... raise AppRegistryNotReady("Apps aren't loaded yet.") django.core.exceptions.AppRegistryNotReady: Apps aren't loaded yet.
なお、単なるpython
コマンドでもDjangoを使うようにするには以下のようにすればよいらしい(myproject
のところはプロジェクト名)
$ export DJANGO_SETTINGS_MODULE=myproject.settings $ python >>> import django >>> django.setup() >>> from boards.models import Board
APIでオブジェクト作成
対話型シェルを起動したら最初にモデルをインポートする。
>>> from boards.models import Board
新しいBoardオブジェクトの作成は以下のようにする。
この場合はsave()
は明示的に呼ぶ必要があり、save()
が成功すると自動的にid
が振られる。
また、各フィールドにはboard.name
のようにアクセス可能。
>>> board = Board(name='Django', description='This is a board about Django.') >>> board.save() >>> board.id 1 >>> board.name 'Django' >>> board.description 'This is a board about Django.'
フィールドの値を変更することもできる。
>>> board.description = 'Django discussion board.' >>> board.save() >>> board.description 'Django discussion board.'
また、オブジェクトの作成は以下のようにobjects.create
でもできる。
>>> board = Board.objects.create(name='Python', description='General discussion about Python.') >>> board.id 2 >>> board.name 'Python' >>> board.description 'General discussion about Python.'
作成したオブジェクトはデータベースに反映されている。
sqlite> select * from boards_board; 1|Django|Django discussion board. 2|Python|General discussion about Python.
__str__()メソッド
先ほど登録したオブジェクトをall()
で表示してみる。
>>> Board.objects.all() <QuerySet [<Board: Board object (1)>, <Board: Board object (2)>]>
返り値はQuerySet
と呼ばれるものだが<Board: Board object (1)>
がオブジェクトの表現として役に立っていないのでBoardモデルに__str__()
メソッドを追加して修正してみる。
exit()
で対話型シェルを抜けてboards/models.py
に__str__()
を追加する。
class Board(models.Model): name = models.CharField(max_length=30, unique=True) description = models.CharField(max_length=100) def __str__(self): return self.name
これでオブジェクトの表現が見やすくなる。ドキュメントによると__str__()
メソッドを追加することは重要とのこと。
>>> Board.objects.all()
<QuerySet [<Board: Django>, <Board: Python>]>
あなた自身のインタラクティブシェルでの表示での利便性のためだけではなく、Djangoの自動生成adminでオブジェクトの表現として使用されるという理由からも __str__() メソッドをモデルに追加することは重要です。
その他のAPI
all()
の返り値のQuerySet
はリストのように取り扱うことができる。
>>> boards_list = Board.objects.all() >>> for board in boards_list: ... print(board.description) ... Django discussion board. General discussion about Python.
get()
メソッドを使うとオブジェクトを1つだけ取得できる。
>>> django_board = Board.objects.get(id=1) >>> django_board.name 'Django'
存在しないidを指定すると例外が投げられる。
>>> board = Board.objects.get(id=3) boards.models.DoesNotExist: Board matching query does not exist.
get()
メソッドは別のフィールを指定することもできる。
>>> Board.objects.get(name='Django') <Board: Django> >>> Board.objects.get(name='django') boards.models.DoesNotExist: Board matching query does not exist.```
まとめ
python manage.py shell
で対話型シェルを起動board = Board()
はオブジェクトを保存せずに作成board.save()
でオブジェクトを保存Board.objects.create(name='...', description='...')
はオブジェクトの作成&保存Board.objects.all()
で全オブジェクトを取得Board.objects.get(id=1)
で条件に一致したオブジェクトを取得
追記:対話型シェルを便利にしたい場合は下記記事を参照。