用Docker+Django+Next+TypeScript+ECS创建应用的故事(2) ~ 从Django的初始设置到创建模型的部分 ~

首先

接下来是上一次的延续。

前一个文章:关于使用Docker+Django+Next+TypeScript+ECS创建应用程序的故事(1)〜准备篇〜
后一个文章:关于使用Docker+Django+Next+TypeScript+ECS创建应用程序的故事(3)〜从Django模式创建到数据获取〜

这次的文章写了关于Django项目的初始设置到创建模型的过程。
我们选择了Django作为后端,并采用了graphene-django来将Django转化为API。
关于graphene-django,我们参考了下面的文章。

 

1. 初步设置

我将创建用于开发和测试环境的settings以及用于生产环境的settings。此外,我将创建一个名为.env的文件来管理生产环境的SECRET_KEY,并通过django-environ包进行管理。

myProject/
    app/
+   .env
        app/
        settings.py
+          dev_settings.py
+          prod_settings.py
        ...
    settings.py

这里记载了在所有开发环境中共同的部分。SECRET_KEY和DEBUG已经在不同的环境设置中进行了记录。
ALLOWED_HOSTS通过环境变量进行设置,可以在每个环境中进行更改。
此外,还进行了graphene-django和数据库配置的更改,将语言设置为日语,时区设置为日本。
同时,AUTH_USER_MODEL已被设置为稍后创建的User模型。

+ import os
  from pathlib import Path

  BASE_DIR = Path(__file__).resolve().parent.parent
-
- SECRET_KEY = '1234567890**************************'
- DEBUG = True 
- 
- ALLOWED_HOSTS = []
+ ALLOWED_HOSTS = [os.environ['ALLOWED_HOST']]
 
  INSTALLED_APPS = [
      'django.contrib.admin',
      'django.contrib.auth',
      'django.contrib.contenttypes',
      'django.contrib.sessions',
      'django.contrib.messages',
      'django.contrib.staticfiles',
+     'graphene_django',
+     'corsheaders',
+     'api.apps.ApiConfig',
  ]

  MIDDLEWARE = [
      'django.middleware.security.SecurityMiddleware',
      'django.contrib.sessions.middleware.SessionMiddleware',
      'django.middleware.common.CommonMiddleware',
      'django.middleware.csrf.CsrfViewMiddleware',
      'django.contrib.auth.middleware.AuthenticationMiddleware',
      'django.contrib.messages.middleware.MessageMiddleware',
      'django.middleware.clickjacking.XFrameOptionsMiddleware',
+     'corsheaders.middleware.CorsMiddleware',
  ]

+
+ CORS_ORIGIN_WHITELIST = [
+     os.environ['FRONT_URI']
+ ]
+
+ GRAPHWL_JWT = {
+     'JWT_VERIFY_EXPORATION': False,
+ }
+
+ GRAPHENE = {
+     'SCHEMA':
+         'app.schema.schema',
+         'MIDDLEWARE': [
+             'graphql_jwt.middleware.JSONWebTokenMiddleware',
+         ],
+ }
+ 
+ AUTHENTICATION_BACKENDS = [
+     'graphql_jwt.backends.JSONWebTokenBackend',
+     'django.contrib.auth.backends.ModelBackend',
+ ]

  ROOT_URLCONF = 'app.urls'

  TEMPLATES = [
      {
          'BACKEND': 'django.template.backends.django.DjangoTemplates',
          'DIRS': [],
          'APP_DIRS': True,
          'OPTIONS': {
              'context_processors': [
                  'django.template.context_processors.debug',
                  'django.template.context_processors.request',
                  'django.contrib.auth.context_processors.auth',
                  'django.contrib.messages.context_processors.messages',
              ],
          },
      },
  ]

  WSGI_APPLICATION = 'app.wsgi.application'

  DATABASES = {
      'default': {
-          'ENGINE': 'django.db.backends.sqlite3',
+          'ENGINE': 'django.db.backends.postgresql',
-          'NAME': BASE_DIR / 'db.sqlite3',
+          'NAME': os.environ['DB_NAME'],
+          'USER': os.environ['DB_USER'],
+          'HOST': os.environ['DB_HOST'],
+          'PORT': 5432,
       }
  }

  AUTH_PASSWORD_VALIDATORS = [
      {
          'NAME': 'django.contrib.auth.password_validation.UserAttributeSimilarityValidator',
      },
      {
          'NAME': 'django.contrib.auth.password_validation.MinimumLengthValidator',
      },
      {
          'NAME': 'django.contrib.auth.password_validation.CommonPasswordValidator',
      },
      {
          'NAME': 'django.contrib.auth.password_validation.NumericPasswordValidator',
      },
  ]

- LANGUAGE_CODE = 'en-us'
+ LANGUAGE_CODE = 'ja'
-
- TIME_ZONE = 'UTC'
+ TIME_ZONE = 'Asia/Tokyo'

  USE_I18N = True

  USE_L10N = True

  USE_TZ = True
+
+ AUTH_USER_MODEL = 'api.CustomUser'

  STATIC_URL = '/static/'
+
+ STATIC_ROOT = os.path.join(BASE_DIR, 'static')
    dev_settings.py

我正在記錄開發環境和測試環境的設定。SECRET_KEY的值與生產環境不同。

from .settings import *

DEBUG = True

SECRET_KEY = '1234567890**************************'
    prod_settings.py

我在这里写下了用于生产环境的设置。
SECRET_KEY通过django-environ在.env文件中进行了记录。

import os
import environ

from .settings import *

env = environ.Env()
env.read_env(os.path.join(BASE_DIR, '.env'))

DEBUG = False

SECRET_KEY = env('SECRET_KEY')
    • .env

 

    本番環境用のSECRET_KEYを記載しています。
SECRET_KEY=abcdefghijk************************

2. 建立模型

我将创建User模型和Profile模型。
将其记录在api文件夹的models.py文件中。

    • models.py

 

    • UserモデルはDjango標準のAbstractBaseUserをオーバーライドして作成します。

 

    email、passwordでの認証にするため、name属性はProfileモデルに分け、Userモデルは必要最低限の属性にしています。

from django.db import models
from django.contrib.auth.models import AbstractBaseUser, BaseUserManager, PermissionsMixin

class CustomUserManager(BaseUserManager):
    def create_user(self, email, password=None):

        if not email:
            raise ValueError('email is must')

        user = self.model(email=self.normalize_email(email))
        user.set_password(password)
        user.save(using=self._db)

        return user

    def create_superuser(self, email, password):
        user = self.create_user(email, password)
        user.is_staff = True
        user.is_superuser = True
        user.save(using=self._db)

        return user

class CustomUser(AbstractBaseUser, PermissionsMixin):
    email = models.EmailField(max_length=50, unique=True)
    is_active = models.BooleanField(default=True)
    is_staff = models.BooleanField(default=False)

    objects = CustomUserManager()

    USERNAME_FIELD = 'email'

    def __str__(self):
        return self.email

class Profile(models.Model):
    nickname = models.CharField(max_length=20)
    user = models.OneToOneField(
        CustomUser, related_name="profile",
        on_delete=models.CASCADE
    )

    def __str__(self):
        return self.nickname

    • admin.py

 

    Django標準の管理画面にてUserモデルとProfileモデルをCRUD操作できるように記載します。
from django.contrib import admin
from .models import CustomUser, Profile

admin.site.register(CustomUser)
admin.site.register(Profile)

    • docker-compose.yml

 

    Djangoコンテナ起動時に、開発環境用のsettingsを使用するように修正します。
  version: "3"

  services:
    app:
      build:
        context: .
      ports:
        - "8000:8000"
      volumes:
        - ./app:/app
-      command: sh -c "python manage.py migrate &&
-       python manage.py runserver 0.0.0.0:8000"
+      command: sh -c "python manage.py migrate --settings app.dev_settings &&
+       python manage.py runserver 0.0.0.0:8000 --settings app.dev_settings"
      environment:
        - FRONT_URI=http://localhost:3000
        - ALLOWED_HOST=localhost
        - DB_HOST=db
        - DB_NAME=app
        - DB_USER=postgres
        - DB_PASS=supersecretpassword
      depends_on:
        - db
・・・

通过以下命令,更新数据库并创建管理员用户。

$ make migrate
$ make admin

重新启动容器,然后访问localhost:8000/admin。
如果容器正常工作,将显示管理员登录页面。
请使用先前创建的管理员账户登录。
登录后,将跳转到可以执行User模型和Profile模型的CRUD操作的页面。

Django管理者後のログインページ

总结了

我这次进行了对设置的修正,创建了User模型和Profile模型。
下次,我希望将Django作为Graphql,创建模式,并编写在浏览器中获取数据的部分。

用Docker+Django+Next+TypeScript+ECS创建应用的故事(3) – 从创建Django模式到获取数据的过程。

广告
将在 10 秒后关闭
bannerAds