こちらの記事の続きです。 programming-gogogogo.hatenablog.com
上記の記事でフロントエンドをコーディングしたので、今回はバックエンドを構築したいと思います。
ルールは以下にしました。
- 技術記事のコードはコピペしない
- 公式ドキュメントは見てOK
- ChatGPT、GitHub Copilotを使うのはOK
- ChatGPT、GitHub Copilotをどう使うか書いてる技術記事を参考にするのはOK
今回は以下の順番で進めます。
- Docker-composeを用意して、PythonとPostgreSQLのコンテナを構築する
- PythonコンテナでDjango REST Framework(DRF)を立ち上げる
- DRFでUsersモデルを作成する
- Usersモデルに対してCRUD処理を実装する
1. Docker-composeを用意して、PythonとPostgreSQLのコンテナを構築する
docker-compose.ymlの書き方もChatGPTに聞こうかと思いましたが、長くなりそうなので今回は以下の記事の方法でやってみます。
「Create Dev container」の次は「Python 3 & PostgreSQL」を選択するようにしました。
以下のdevcontainer.json、docker-compose.yml、Dockerfileが作成されPythonとPostgreSQLのコンテナが立ち上がりました。
devcontainer.json
// For format details, see https://aka.ms/devcontainer.json. For config options, see the // README at: https://github.com/devcontainers/templates/tree/main/src/postgres { "name": "Python 3 & PostgreSQL", "dockerComposeFile": "docker-compose.yml", "service": "app", "workspaceFolder": "/workspaces/${localWorkspaceFolderBasename}" // Features to add to the dev container. More info: https://containers.dev/features. // "features": {}, // Use 'forwardPorts' to make a list of ports inside the container available locally. // This can be used to network with other containers or the host. // "forwardPorts": [5000, 5432], // Use 'postCreateCommand' to run commands after the container is created. // "postCreateCommand": "pip install --user -r requirements.txt", // Configure tool-specific properties. // "customizations": {}, // Uncomment to connect as root instead. More info: https://aka.ms/dev-containers-non-root. // "remoteUser": "root" }
docker-compose.yml
version: '3.8' services: app: build: context: .. dockerfile: .devcontainer/Dockerfile volumes: - ../..:/workspaces:cached # Overrides default command so things don't shut down after the process ends. command: sleep infinity # Runs app on the same network as the database container, allows "forwardPorts" in devcontainer.json function. network_mode: service:db # Use "forwardPorts" in **devcontainer.json** to forward an app port locally. # (Adding the "ports" property to this file will not forward from a Codespace.) db: image: postgres:latest restart: unless-stopped volumes: - postgres-data:/var/lib/postgresql/data environment: POSTGRES_USER: postgres POSTGRES_DB: postgres POSTGRES_PASSWORD: postgres # Add "forwardPorts": ["5432"] to **devcontainer.json** to forward PostgreSQL locally. # (Adding the "ports" property to this file will not forward from a Codespace.) volumes: postgres-data:
Dockerfile
FROM mcr.microsoft.com/devcontainers/python:0-3.11 ENV PYTHONUNBUFFERED 1 # [Optional] If your requirements rarely change, uncomment this section to add them to the image. # COPY requirements.txt /tmp/pip-tmp/ # RUN pip3 --disable-pip-version-check --no-cache-dir install -r /tmp/pip-tmp/requirements.txt \ # && rm -rf /tmp/pip-tmp # [Optional] Uncomment this section to install additional OS packages. # RUN apt-get update && export DEBIAN_FRONTEND=noninteractive \ # && apt-get -y install --no-install-recommends <your-package-list-here>
次にChatGPTにDjango REST FrameworkとPostgreSQLを繋げる方法を聞いてみます。
入力
Tell me how to build Django REST Framework and connect it with PostgreSQL.
出力
Sure, here are the steps to build a Django REST Framework and connect it with PostgreSQL:
pip install Django pip install djangorestframework
- Install the PostgreSQL database and psycopg2 library:
sudo apt-get install postgresql postgresql-contrib pip install psycopg2
- Create a new Django project:
django-admin startproject project_name cd project_name
- Create a new Django app:
python manage.py startapp app_name
- Configure the PostgreSQL database settings in your Django project's settings.py file:
DATABASES = { 'default': { 'ENGINE': 'django.db.backends.postgresql_psycopg2', 'NAME': 'database_name', 'USER': 'database_user', 'PASSWORD': 'database_password', 'HOST': 'localhost', 'PORT': '5432', } }
Replace database_name, database_user, and database_password with your own values.
- Create a new model in your Django app's models.py file:
from django.db import models class ExampleModel(models.Model): field1 = models.CharField(max_length=100) field2 = models.CharField(max_length=100)
- Create a new serializer in your Django app's serializers.py file:
from rest_framework import serializers from .models import ExampleModel class ExampleSerializer(serializers.ModelSerializer): class Meta: model = ExampleModel fields = '__all__'
- Create a new view in your Django app's views.py file:
from rest_framework import viewsets from .models import ExampleModel from .serializers import ExampleSerializer class ExampleViewSet(viewsets.ModelViewSet): queryset = ExampleModel.objects.all() serializer_class = ExampleSerializer
- Add a URL pattern for the view in your Django app's urls.py file:
from django.urls import include, path from rest_framework import routers from .views import ExampleViewSet router = routers.DefaultRouter() router.register(r'example', ExampleViewSet) urlpatterns = [ path('', include(router.urls)), ]
- Run the migrations to create the database tables:
python manage.py makemigrations python manage.py migrate
- Start the development server:
python manage.py runserver
Now you should be able to access the API at http://localhost:8000/example/ and perform CRUD operations on your ExampleModel instances.
上記の手順を紹介している公式ドキュメントもあるか聞いてみました。
入力
Thanks. Could you give me the official document which describes how to connect Django REST Framework and PostgreSQL?
出力
Certainly, you can find the official documentation for connecting Django REST Framework and PostgreSQL at the following links:
Django documentation on using PostgreSQL: https://docs.djangoproject.com/en/3.2/ref/databases/#postgresql-notes
Django REST Framework documentation on using PostgreSQL: https://www.django-rest-framework.org/api-guide/databases/#postgresql
These links provide more detailed information and instructions on how to connect Django REST Framework and PostgreSQL, including additional configuration options and troubleshooting tips.
Djangoの方は公式ドキュメントのリンクになっていましたが、Django REST Frameworkの方は存在しないURLになっていました。
提案してもらった手順でDjango REST Frameworkを立ち上げてみます。
pip install Django pip install djangorestframework
sudo apt-get install postgresql postgresql-contrib
こちらのコマンドでは以下のエラーが出ました。
stgresql postgresql-contrib Reading package lists... Done Building dependency tree... Done Reading state information... Done E: Unable to locate package postgresql E: Unable to locate package postgresql-contrib
とりあえずそのまま進めてみます。
pip install psycopg2
django-admin startproject project_name cd project_name
python manage.py startapp app_name
ここまでの操作で、ディレクトリ構成は以下のようになりました。
/workspaces/postgres/project_name $ tree . ├── app_name │ ├── __init__.py │ ├── admin.py │ ├── apps.py │ ├── migrations │ │ └── __init__.py │ ├── models.py │ ├── tests.py │ └── views.py ├── manage.py └── project_name ├── __init__.py ├── __pycache__ │ ├── __init__.cpython-311.pyc │ └── settings.cpython-311.pyc ├── asgi.py ├── settings.py ├── urls.py └── wsgi.py 4 directories, 15 files
次にproject_name/project_name/settings.pyのDATABASESを編集していきます。
DATABASES = { 'default': { 'ENGINE': 'django.db.backends.postgresql_psycopg2', 'NAME': 'postgres', 'USER': 'postgres', 'PASSWORD': 'postgres', 'HOST': 'localhost', 'PORT': '5432', } }
設定値はdocker-compose.ymlで設定したものになります。
通信用のポートはdocker-compose.ymlで指定されていないのでエラーが発生するかも知れませんが、とりあえずそのまま進めてみます。
project_name/app_name/models.pyを以下のように編集します。
from django.db import models class UserModel(models.Model): name = models.CharField(max_length=50) email = models.EmailField(max_length=100)
次にserializerを作成します。
touch app_name/serializers.py
serializer名を書くと以下のようにGitHub Copilotがコードを提案してくれましたのでそのまま使ってみます。
次にviewを作成します。
ここでもGitHub Copilotがコードを提案してくれました。
ほぼ決まったパターンのコードはGitHub Copilotが正確な提案をしてくれる印象です。 まずは提案されたコードを読んで、それに対して要件に応じて修正を加える流れが多くなりそうです。
次にapp_name/urls.pyを作成します。
touch app_name/urls.py
app_name/urls.pyを以下のように編集します。
from django.urls import path, include from rest_framework import routers from .views import UserViewSet router = routers.DefaultRouter() router.register("users", UserViewSet) urlpatterns = [ path("", include(router.urls)), ]
app_name/urls.pyをproject_name/project_name/urls.pyに追記します。 (ここはChatGPTの回答にはない部分でした)
from django.contrib import admin from django.urls import path, include urlpatterns = [ path("admin/", admin.site.urls), path("api/", include("app_name.urls")), # 追記 ]
次にマイグレーションを実行します。
python manage.py makemigrations
すると以下のエラーになりました。
RuntimeError: Model class app_name.models.UserModel doesn't declare an explicit app_label and isn't in an application in INSTALLED_APPS.
そういえばsettings.pyのINSTALLED_APPSにapp_nameを追加していなかったので追加します。ここもChatGPTの回答にはない部分でしたので、自分でDjangoの仕組みを理解しておくか、ChatGPTに何回か質問して正確な情報を得るなどの対応が必要そうです。
INSTALLED_APPS = [ "django.contrib.admin", "django.contrib.auth", "django.contrib.contenttypes", "django.contrib.sessions", "django.contrib.messages", "django.contrib.staticfiles", "rest_framework", # 追記 "app_name", # 追記 ]
再度makemigrationsを実行すると成功しました。
vscode ➜ /workspaces/postgres/project_name $ python manage.py makemigrations Migrations for 'app_name': app_name/migrations/0001_initial.py - Create model UserModel
次にmigrateを実行します。
python manage.py migrate
こちらも成功しました。
次にローカルサーバーを起動します。
python manage.py runserver
すると無事ブラウザからアクセスできました。
画面からデータを入力してPOSTも成功しました。
今度はcurlコマンドを送ってみました。正常にデータが取得できましたので、動作に問題なさそうです。
curl http://localhost:8000/api/users/ [{"id":1,"name":"testuser1","email":"testuser1@email.com"}]
以上でDjangoとPostgreSQLの連携ができました。 docker-compose.ymlにポートを空けるを指定する必要があるかと思ってましたが、問題ないみたいでした。このあたりは別の機会に深掘りします。
一応PostgreSQLのコンテナに入って確認してみたいと思います。 コンテナにはVSCodeのGUIから「Attach shell」で入りました。 そこからPostgreSQLにログインする手順をChatGPTに質問してみました。
入力
Tell me how to connect PostgreSQL from terminal. Should I use psql command?
出力
Yes, you can connect to PostgreSQL from the terminal using the psql command, which is the PostgreSQL interactive terminal. Here are the steps to connect to a PostgreSQL database using psql:
Open the terminal on your computer.
Type the following command to connect to the PostgreSQL server:
psql -h [server] -p [port] -U [username] -d [database_name]
Replace [server] with the hostname or IP address of the server where PostgreSQL is installed, [port] with the port number (default is 5432), [username] with the username that you use to connect to PostgreSQL, and [database_name] with the name of the database that you want to connect to.
Press Enter.
If you have entered the correct information, you will see a prompt that looks like this:
postgres=#
This means that you are connected to the PostgreSQL database.
For example, you can list all the tables in the current database by typing:
\dt
You can exit the psql prompt by typing:
\q
This will disconnect you from the PostgreSQL database and return you to the terminal prompt.
Note: Before using psql command, make sure that PostgreSQL is installed on your computer and the PostgreSQL server is running.
上記手順でPostgreSQLにログインできました。 以下のSQLでデータが入っていることが確認できました。
postgres=# select * from app_name_usermodel; id | name | email ----+-----------+--------------------- 1 | testuser1 | testuser1@email.com (1 row)
これでDjango REST FrameworkとPostgreSQLの連携ができましたので、次はVue.jsでDjango REST FrameworkのAPIからデータを取得し画面に表示するところまでやってみようと思います。