Django REST Frameworkでいろいろコードを書いて動作を確認しています。
このブログでは自分の整理用に手を動かした記録をつけておきたいと思いますので、手順や内容はごちゃごちゃしてしまうかも知れません。
Pythonが動作する環境はVSCodeのDev Containerで構築しました。Dockerイメージはデフォルトでmcr.microsoft.com/devcontainers/python:0-3.11
が指定されています。
pip freezeコマンドでまだ何もライブラリがインストールされていないことを確認。
pip freeze
DjangoとDjango REST Frameworkをインストールします。 後々慣れてきたらrequirements.txtを用意するかDockerfileでインストールするコマンドを書いておきたいと思います。
pip install django pip install djangorestframework
pip freezeすると以下の結果になりました。
ライブラリのインストールされている場所を確認します。
python >>> import django >>> print(django.__file__) /home/vscode/.local/lib/python3.11/site-packages/django/__init__.py
確かvenvを有効化していたらvenvのlibあたりにインストールされたと思いますが、今回はvenvを有効化していないので上記のパスになっていると推測します。 Pythonの仮想環境のベストプラクティスについても深掘りしたいところですが、今はDjangoの使い方に慣れたいので後回しにします。
pythonの対話型ターミナルをquit()で抜けます。
quit()
django-adminコマンドで新規プロジェクトを作成します。
vscode ➜ /workspaces/python-5 $ django-admin startproject drfproject vscode ➜ /workspaces/python-5 $ tree . └── drfproject ├── drfproject │ ├── __init__.py │ ├── asgi.py │ ├── settings.py │ ├── urls.py │ └── wsgi.py └── manage.py
この時点でローカルサーバーを起動することができます。
vscode ➜ /workspaces/python-5 $ cd drfproject/ vscode ➜ /workspaces/python-5/drfproject $ python manage.py runserver
runserverを実行するとdrfprojectディレクトリにdb.sqlite3ができていました。
vscode ➜ /workspaces/python-5 $ tree . └── drfproject ├── db.sqlite3 ├── drfproject │ ├── __init__.py │ ├── __pycache__ │ │ ├── __init__.cpython-311.pyc │ │ ├── settings.cpython-311.pyc │ │ ├── urls.cpython-311.pyc │ │ └── wsgi.cpython-311.pyc │ ├── asgi.py │ ├── settings.py │ ├── urls.py │ └── wsgi.py └── manage.py 3 directories, 11 files
新規にblogというappを作成してみます。
vscode ➜ /workspaces/python-5/drfproject $ python manage.py startapp blog vscode ➜ /workspaces/python-5/drfproject $ cd .. vscode ➜ /workspaces/python-5 $ tree . └── drfproject ├── blog │ ├── __init__.py │ ├── admin.py │ ├── apps.py │ ├── migrations │ │ └── __init__.py │ ├── models.py │ ├── tests.py │ └── views.py ├── db.sqlite3 ├── drfproject │ ├── __init__.py │ ├── __pycache__ │ │ ├── __init__.cpython-311.pyc │ │ ├── settings.cpython-311.pyc │ │ ├── urls.cpython-311.pyc │ │ └── wsgi.cpython-311.pyc │ ├── asgi.py │ ├── settings.py │ ├── urls.py │ └── wsgi.py └── manage.py 5 directories, 18 files
drfproject/blog/models.py
にUserモデルを定義してみます。
from django.db import models class User(models.Model): name = models.CharField(max_length=100) age = models.IntegerField()
makemigrationsコマンドを実行すると、no changes detectedになりました。
vscode ➜ /workspaces/python-5 $ python drfproject/manage.py makemigrations No changes detected
確かsettings.pyにINSTALLED_APPという項目があったはずなので、追加してみます。
INSTALLED_APPS = [ "django.contrib.admin", "django.contrib.auth", "django.contrib.contenttypes", "django.contrib.sessions", "django.contrib.messages", "django.contrib.staticfiles", "blog", # 追加 ]
再度makemigrationsを実行すると処理が行われました。
vscode ➜ /workspaces/python-5 $ python drfproject/manage.py makemigrations Migrations for 'blog': drfproject/blog/migrations/0001_initial.py - Create model User
一度管理画面からモデルにデータを入れたいので、ローカルサーバーを起動し、http://localhost:8000/admin
にアクセスすると以下の画面が表示されます。
まだsuperuserを作成していなかったので作成します。
vscode ➜ /workspaces/python-5 $ python drfproject/manage.py createsuperuser You have 19 unapplied migration(s). Your project may not work properly until you apply the migrations for app(s): admin, auth, blog, contenttypes, sessions. Run 'python manage.py migrate' to apply them.
migrate実行前のmigrationがあるとcreatesuperuserコマンドは実行できないようでした。 migrateを実行します。
vscode ➜ /workspaces/python-5 $ python drfproject/manage.py migrate Operations to perform: Apply all migrations: admin, auth, blog, contenttypes, sessions Running migrations: Applying contenttypes.0001_initial... OK Applying auth.0001_initial... OK Applying admin.0001_initial... OK Applying admin.0002_logentry_remove_auto_add... OK Applying admin.0003_logentry_add_action_flag_choices... OK Applying contenttypes.0002_remove_content_type_name... OK Applying auth.0002_alter_permission_name_max_length... OK Applying auth.0003_alter_user_email_max_length... OK Applying auth.0004_alter_user_username_opts... OK Applying auth.0005_alter_user_last_login_null... OK Applying auth.0006_require_contenttypes_0002... OK Applying auth.0007_alter_validators_add_error_messages... OK Applying auth.0008_alter_user_username_max_length... OK Applying auth.0009_alter_user_last_name_max_length... OK Applying auth.0010_alter_group_name_max_length... OK Applying auth.0011_update_proxy_permissions... OK Applying auth.0012_alter_user_first_name_max_length... OK Applying blog.0001_initial... OK Applying sessions.0001_initial... OK
再度createsuperuserを実行すると成功しました。
vscode ➜ /workspaces/python-5 $ python drfproject/manage.py createsuperuser Username (leave blank to use 'vscode'): test Email address: test@email.com Password: Password (again):
作成したsuperuserで管理画面にアクセスすると、Userモデルが参照できませんでした。 確かblog/admin.pyに登録する必要があったはずなので、ドキュメントを調べてみます。
Djangoの公式ドキュメントに情報がありました。 https://docs.djangoproject.com/en/4.1/ref/contrib/admin/#modeladmin-objects
ドキュメントの例を参考にdrfproject/blog/admin.py
を以下のようにしてみました。
from django.contrib import admin from .models import User class UserAdmin(admin.ModelAdmin): pass admin.site.register(User, UserAdmin)
すると管理画面でもUserモデルが表示されました。 また、ドキュメントにはModelAdminクラスはなくても良いよ的な記述もあったので以下のコードも試してみたところ同じく管理画面にUserモデルは表示されていました。
from django.contrib import admin from .models import User # class UserAdmin(admin.ModelAdmin): # pass # admin.site.register(User, UserAdmin) admin.site.register(User)
おそらくpassするだけじゃなくて何かロジックを書きたい時はUserAdminクラスを定義する必要があるけど、そうじゃないなら省略しても動作に変わりはないっぽいなと解釈しました。
管理画面からUserデータを登録しました。
APIのリクエストを受けるにはViewの設定が必要だったはずなので、作成してみます。 DRFではViewにクラスを定義するのが基本な気がするけど、いろいろ試したいので関数を定義してみます。
drfproject/blog/views.py
from django.http import HttpResponse def home(request): return HttpResponse("HELLO\n")
drfproject/drfproject/urls.py
from django.contrib import admin from django.urls import path from blog import views urlpatterns = [ path("admin/", admin.site.urls), path("blog/", views.home) ]
するとhttp://localhost:8000/blog/
にリクエストを投げるとレスポンスが返ってくることが確認できました。
vscode ➜ /workspaces/python-5 $ curl http://localhost:8000/blog/ HELLO
Viewに関数を定義してrouterでエンドポイントと紐づけることができるようです。 ここまではモデルも介さずただ文字列を返す関数を実行しているだけなので、次はViewにDRFで提供されてるクラスを定義してみます。