Django

「Django REST Framework」でAPIを作る。

Django REST Frameworkを使ってAPIを作る過程のメモです。(途中)

この記事ではAPIを作るまでのコマンドやコードの中身を中心に書いていきます。各作業の解説をあわせて書くと長くなりそうなので、それぞれ別記事にしてまとめいこうと考えていきます。

今回の完成イメージ

  • 「記事一覧データ」を取得できる(List)
  • 「記事詳細データ」を取得できる(Detail)
  • ユーザー登録なしでAPIが利用できる状態(※今回は認証機能なし)

全体の作業フロー

  1. 必要なパッケージをインストール
  2. Djangoのプロジェクトを作る
  3. Djangoのアプリケーションを作る
  4. settings.py」を変更する
  5. models.py」を変更する
  6. serializers.py」を変更する
  7. urls.py」を変更する
  8. views.py」を変更する
  9. Githubにアップロードする
  10. Herokuにデプロイする

1. 必要なパッケージをインストールする

$ pip install django
$ pip install django-cors-headers
$ pip install djangorestframework
$ pip install djoser
$ pip install python-decouple
$ pip install dj-database-url
$ pip install dj_static

$ pip install django django-cors-headers djangorestframework djoser python-decouple dj-database-url dj_static

2. Djangoのプロジェクトを作成する

まずはDjangoのプロジェクトを置くためのディレクトリを作成し、そのディレクトリに移動します。

$ mkdir rest_api_project    # 「rest_api_project」部分は自由(ディレクトリ名)
$ cd rest_api_project

作成したディレクトリ内で、Djangoのプロジェクトを作成します。

$ django-admin startproject rest_api .    # 「rest_api」部分は自由(プロジェクト名)

3. Djangoのアプリケーションを作成する

$ django-admin startapp api    # 「api」部分は自由(アプリケーション名)
【この時点でのディレクトリ構造】

rest_api_project
 ├ api
 ├ rest_api
 └ manage.py

4. 「settings.py」を変更する

rest_api直下にある「settings.py」を編集していきます。

from datetime import timedelta  # 追加
from decouple import config  # 追加
from dj_database_url import parse as dburl  # 追加


INSTALLED_APPS = [
  ...,
  'rest_framework',  # 追加
	'api.apps.ApiConfig',  # 追加
	'corsheaders',  # 追加
	'djoser',  # 追加
]

MIDDLEWARE = [
  'corsheaders.middleware.CorsMiddleware',  # 追加
  ...
]

# 追加
CORS_ORIGIN_WHITELIST = [
	"http://localhost:3000",
]

default_dburl = 'sqlite:///' + str(BASE_DIR / "db.sqlite3")  # 追加

# "DATABASES"を変更
DATABASES = {
	'default': config('DATABASE_URL', default=default_dburl, cast=dburl),
}

TIME_ZONE = 'Asia/Tokyo'  # 変更

# 追加
STATIC_URL = '/static/'
STATIC_ROOT = str(BASE_DIR / 'staticfiles')

「.env」を作成する(環境変数の設定)

トップディレクトリ直下に「.env」ファイルを作成します。

api/settings.pyに記載されている「SECRET_KEY」と「DEBUG」をenvファイルに記載します。

SECRET_KEY=[シークレットキー]
DEBUG=False

また元々のapi/settings.pyの記載を変更して、「.env」ファイルから読み込むようにします。

from decouple import config  # 追加

SECRET_KEY = config('SECRET_KEY')  # 追加
DEBUG = config('DEBUG')  # 追加

5. 「models.py」(admin.py)を変更する

「api」ディレクトリ直下にある「models.py」を編集します。これでデータベースのテーブルとカラムが定義されます。

from django.db import models

class Post(models.Model):
	title = models.CharField(max_length=50)
	content = models.CharField(max_length=500)
	created_at = models.DateTimeField(auto_now_add=True)

	def __str__(self):
		return self.title

コマンドを入力してデータベースを作成/更新します。

$ python manage.py makemigrations
$ python manage.py migrate

6. 「serializers.py」を変更する

「api」ディレクトリ直下に「serializers.py」を作成します。

from rest_framework import serializers
from .models import Post


class PostSerializer(serializers.ModelSerializer):
	created_at = serializers.DateTimeField(format="%Y-%m-%d %H:%M:%S", read_only=True)

	class Meta:
		model = Post
		fields = ('id', 'title', 'content', 'created_at')

7. 「urls.py」を変更する

「api」ディレクトリ直下に「urls.py」を作成します。

from django.urls import path
from api.views import PostListView, PostRetrieveView


urlpatterns = [
    path('posts/', PostListView.as_view(), name='posts'),
    path('post/<str:pk>/', PostRetrieveView.as_view(), name='post-detail'),
]

「rest_api」ディレクトリ直下に「urls.py」を作成します。

from django.contrib import admin
from django.urls import path, include

urlpatterns = [
  path('admin/', admin.site.urls),
	path('api/', include('api.urls')),  # 追加
]

8. 「views.py」を変更する

「api」ディレクトリ直下にある「views.py」を編集します。

from .models import Post
from .serializers import PostSerializer
from rest_framework import generics
from rest_framework.permissions import AllowAny


class PostListView(generics.ListAPIView):
    queryset = Post.objects.all()
    serializer_class = PostSerializer
    permission_classes = (AllowAny,)


class PostRetrieveView(generics.RetrieveAPIView):
    queryset = Post.objects.all()
    serializer_class = PostSerializer
    permission_classes = (AllowAny,)

9. Githubにアップロードする

「.gitignore」を作成する

Githubのリポジトリを作成する

Githubにプッシュする

10. Herokuにデプロイする

必要なライブラリをインストールする

$ pip install gunicorn
$ pip install psycopg2-binary

$ pip install gunicorn psycopg2-binary

「requirements.txt」を作成する

$ pip freeze > requirements.txt  

「Procfile」を作成する

web: gunicorn rest_api.wsgi --log-file -    # 「rest_api」部分は自由(プロジェクト名)

「runtime.txt」を作成する

python-3.8.12

「settings.py」を編集する

# 変更
ALLOWED_HOSTS = ['nextjs-restapi.herokuapp.com']

↑↑↑
ALLOWED_HOSTS = ['[herokuのアプリケーション名].herokuapp.com']

11. 動作確認テストする

admin.pyで管理画面の設定をする

from django.contrib import admin
from .models import Post

admin.site.register(Post)

スーパーユーザーを作成する

管理画面を操作するためのスーパーユーザーを作成します。

$ python manage.py createsuperuser  # (ローカル環境に作成)
$ heroku run python manage.py createsuperuser -app [herokuリポジトリ名]  # (heroku環境に作成)

テストデータを入れる

エンドポイントにアクセスして確認する

おまけ:仮想環境で開発する

【Django】「ImportError: Couldn’t import Django. Are you sure it’s …」のエラーが出た。

Djangoアプリケーションを作ろうと思って、その中でターミナルでmanage.pyを実行しようと思ったところこのエラーが出ました。

今回のエラー文

ImportError: Couldn't import Django. Are you sure it's installed and available on your PYTHONPATH environment variable? Did you forget to activate a virtual environment?

(直訳)
1. [インポートエラー] Django がインポートできません!
2. Djangoはインストールされていますか、そしてそれが 環境変数 PYTHONPATH している場所にありますか?
3. 仮想環境(virtualenv)を開始することを忘れていませんか?

https://teratail.com/questions/130346

エラーの解消法

仮想環境に入って、再度「django」をインストールして実行したら動きました。

Pycharmだと「Preferences」→「Project Interpreter」で仮想環境を指定して後に、ターミナルを再起動しないといけなかったみたいです。

エラーが起きた原因

今回はAnacondaで仮想環境を作って、そこで「python manage.py runserver」を実行しようとしていました。

ところがその仮想環境に「django」がインストールされていなかったためエラーが起きてしまっていたみたいです 。(仮想環境ではなくローカル環境でインストールしてた…)

とても初歩的なミスをしてしまいました。今後、「いま仮想環境に入っているか」をしっかり確認することを注意していこうと思います。

【Django】SCSSを導入する。

ライブラリのインストール

$ pip install libsass django-compressor django-sass-processor

settingsの追記

INSTALLED_APPS = [
    ...
    'sass_processor',
]

# Sass(SCSS)
SASS_PROCESSOR_ROOT = os.path.join(BASE_DIR, 'static')
SASS_PROCESSOR_INCLUDE_FILE_PATTERN = r'^.+\.(sass|scss)$'
SASS_PRECISION = 8
SASS_OUTPUT_STYLE = 'compressed'
SASS_TEMPLATE_EXTS = ['.html', '.haml']

テンプレートに追記

{% load sass_tags %}

<link rel="stylesheet" href="{% sass_src '【アプリケーション名】/【Sass(scss)ファイル名】' %}">
<link rel="stylesheet" href="{% sass_src 'css/reset.scss' %}">

これで導入できました。