ChatGPTとGitHub Copilotを活用しながらWebアプリケーションを作る【Django REST Framework導入】

こちらの記事の続きです。 programming-gogogogo.hatenablog.com

上記の記事でフロントエンドをコーディングしたので、今回はバックエンドを構築したいと思います。

ルールは以下にしました。

  • 技術記事のコードはコピペしない
  • 公式ドキュメントは見てOK
  • ChatGPT、GitHub Copilotを使うのはOK
  • ChatGPT、GitHub Copilotをどう使うか書いてる技術記事を参考にするのはOK

今回は以下の順番で進めます。

  1. Docker-composeを用意して、PythonPostgreSQLのコンテナを構築する
  2. PythonコンテナでDjango REST Framework(DRF)を立ち上げる
  3. DRFでUsersモデルを作成する
  4. Usersモデルに対してCRUD処理を実装する

1. Docker-composeを用意して、PythonPostgreSQLのコンテナを構築する

docker-compose.ymlの書き方もChatGPTに聞こうかと思いましたが、長くなりそうなので今回は以下の記事の方法でやってみます。

qiita.com

「Create Dev container」の次は「Python 3 & PostgreSQL」を選択するようにしました。

以下のdevcontainer.json、docker-compose.yml、Dockerfileが作成されPythonPostgreSQLのコンテナが立ち上がりました。

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
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"}]

以上でDjangoPostgreSQLの連携ができました。 docker-compose.ymlにポートを空けるを指定する必要があるかと思ってましたが、問題ないみたいでした。このあたりは別の機会に深掘りします。

一応PostgreSQLのコンテナに入って確認してみたいと思います。 コンテナにはVSCodeGUIから「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.

  • You can now run SQL queries or commands in the psql prompt.

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からデータを取得し画面に表示するところまでやってみようと思います。