用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操作的页面。
总结了
我这次进行了对设置的修正,创建了User模型和Profile模型。
下次,我希望将Django作为Graphql,创建模式,并编写在浏览器中获取数据的部分。
用Docker+Django+Next+TypeScript+ECS创建应用的故事(3) – 从创建Django模式到获取数据的过程。