cookiecutter-django 标准化框架实践

一、安装

创建环境

# 1. Create a virtualenv:
(base) ➜  ~ cd /Users/kaiyi/Work/develop/Code/
(base) ➜  Code python3.11 -m venv bit-trading-env

# 2. Activate the virtualenv you have just created:
(base) ➜  Code source bit-trading-env/bin/activate

安装依赖:

pip install "cookiecutter>=1.7.0"

创建项目:

# 3. Generate a new cookiecutter-django project:
$ cookiecutter https://github.com/cookiecutter/cookiecutter-django

(bit-trading-env) (base) ➜  Code cookiecutter https://github.com/cookiecutter/cookiecutter-django
You've downloaded /Users/kaiyi/.cookiecutters/cookiecutter-django before. Is it okay to delete and re-download it? [y/n] (y): y
  [1/27] project_name (My Awesome Project): trading bit
  [2/27] project_slug (trading_bit): tradingbit
  [3/27] description (Behold My Awesome Project!): tradingbit with tradingview
  [4/27] author_name (Daniel Roy Greenfeld): kaiyi
  [5/27] domain_name (example.com): tradingbit.ai
  [6/27] email (kaiyi@tradingbit.ai): 
  [7/27] version (0.1.0): 
  [8/27] Select open_source_license
    1 - MIT
    2 - BSD
    3 - GPLv3
    4 - Apache Software License 2.0
    5 - Not open source
    Choose from [1/2/3/4/5] (1): 1
  [9/27] Select username_type
    1 - username
    2 - email
    Choose from [1/2] (1): 
  [10/27] timezone (UTC): CST
  [11/27] windows (n): 
  [12/27] Select editor
    1 - None
    2 - PyCharm
    3 - VS Code
    Choose from [1/2/3] (1): 2
  [13/27] use_docker (n): y
  [14/27] Select postgresql_version
    1 - 15
    2 - 14
    3 - 13
    4 - 12
    5 - 11
    6 - 10
    Choose from [1/2/3/4/5/6] (1): 2
  [15/27] Select cloud_provider
    1 - AWS
    2 - GCP
    3 - Azure
    4 - None
    Choose from [1/2/3/4] (1): 1
  [16/27] Select mail_service
    1 - Mailgun
    2 - Amazon SES
    3 - Mailjet
    4 - Mandrill
    5 - Postmark
    6 - Sendgrid
    7 - SendinBlue
    8 - SparkPost
    9 - Other SMTP
    Choose from [1/2/3/4/5/6/7/8/9] (1): 1
  [17/27] use_async (n): 
  [18/27] use_drf (n): y
  [19/27] Select frontend_pipeline
    1 - None
    2 - Django Compressor
    3 - Gulp
    4 - Webpack
    Choose from [1/2/3/4] (1): 1
  [20/27] use_celery (n): y
  [21/27] use_mailhog (n): n
  [22/27] use_sentry (n): y
  [23/27] use_whitenoise (n): n
  [24/27] use_heroku (n): n
  [25/27] Select ci_tool
    1 - None
    2 - Travis
    3 - Gitlab
    4 - Github
    5 - Drone
    Choose from [1/2/3/4/5] (1): 4
  [26/27] keep_local_envs_in_vcs (y): y
  [27/27] debug (n): n
 [SUCCESS]: Project initialized, keep up the good work!
(bit-trading-env) (base) ➜  Code     

进入项目:

$ cd tradingbit/
$ ls

(bit-trading-env) (base) ➜  tradingbit ls -l
total 72
-rw-r--r--   1 kaiyi  staff     6 Aug 31 03:58 CONTRIBUTORS.txt
-rw-r--r--   1 kaiyi  staff  1073 Aug 31 03:58 LICENSE
-rw-r--r--   1 kaiyi  staff  2891 Aug 31 03:58 README.md
drwxr-xr-x   4 kaiyi  staff   128 Aug 31 03:58 compose
drwxr-xr-x   8 kaiyi  staff   256 Aug 31 03:58 config
drwxr-xr-x  10 kaiyi  staff   320 Aug 31 03:58 docs
-rw-r--r--   1 kaiyi  staff  1900 Aug 31 03:58 local.yml
drwxr-xr-x   6 kaiyi  staff   192 Aug 31 03:58 locale
-rwxr-xr-x   1 kaiyi  staff  1041 Aug 31 03:58 manage.py
-rw-r--r--   1 kaiyi  staff   671 Aug 31 03:58 merge_production_dotenvs_in_dotenv.py
-rw-r--r--   1 kaiyi  staff  1609 Aug 31 03:58 production.yml
-rw-r--r--   1 kaiyi  staff  1896 Aug 31 03:58 pyproject.toml
drwxr-xr-x   5 kaiyi  staff   160 Aug 31 03:58 requirements
-rw-r--r--   1 kaiyi  staff   400 Aug 31 03:58 setup.cfg
drwxr-xr-x   3 kaiyi  staff    96 Aug 31 03:58 tests
drwxr-xr-x   9 kaiyi  staff   288 Aug 31 03:58 tradingbit
(bit-trading-env) (base) ➜  tradingbit 

将代码推送到代码仓库:

$ git init
$ git add .
$ git commit -m "first awesome cookiecutter-django commit"
$ git remote add origin https://gitee.com/kaiyi/tradingbit.git
$ git push -u origin master

安装依赖:

cd /Users/kaiyi/Work/develop/Code/tradingbit
pip install -r requirements/local.txt

二、安装中间件

mysql8.0

默认安装的是pg14,这里更换为 MySQL8.0,docker方式启动MySQL,https://github.com/mabdullahadeel/cookiecutter-django-mysql

# 拉取镜像
sudo docker pull mysql:5.8

# 
docker run -p 3306:3306 --name mysql \
-v /Users/kaiyi/mydata/mysql/log:/var/log/mysql \
-v /Users/kaiyi/mydata/mysql/data:/var/lib/mysql \
-v /Users/kaiyi/mydata/mysql/conf:/etc/mysql \
-e MYSQL_ROOT_PASSWORD=123456 \
-d mysql:5.8

安装mysqlclient依赖:

# mac 
brew install mysql pkg-config
pip install mysqlclient==2.2.0

redis

1 创建实例并启动

先在宿主机创建需要和Redis容器映射挂载的目录,并手工创建redis配置文件:

mkdir -p /Users/kaiyi/mydata/redis/conf
mkdir -p /Users/kaiyi/mydata/redis/data
touch /Users/kaiyi/mydata/redis/conf/redis.conf

启动:

docker run -p 6379:6379 --name redis \
-v /Users/kaiyi/mydata/redis/data:/data \
-v /Users/kaiyi/mydata/redis/conf/redis.conf:/etc/redis/redis.conf \
-d redis redis-server /etc/redis/redis.conf

2、持久化

现在有一个最大的问题,就是redis默认配置是没有做持久化的,redis的所有数据都存在内存中,如果重启redis再连进来获取原来的数据就获取不到了,想让持久化比较简单,只需要修改配置文件即可。

修改配置文件:·vim /Users/kaiyi/mydata/redis/conf/redis.conf

# 配置持久化
appendonly yes

重启redis:

docker restart redis

直接测试redis服务:

[root@localhost ~]# docker exec -it redis redis-cli
127.0.0.1:6379> set name 'lily'
OK
127.0.0.1:6379> get name
"lily"

exit

三、配置项目

在根目录下创建 .env 文件:

# MySQL
DATABASE_URL=mysql://root:123456@127.0.0.1:3306/tradingbit

# Redis
REDIS_URL=redis://127.0.0.1:6379

# Django
DJANGO_DEBUG=True
#DJANGO_SECRET_KEY=fp2#2%p3z-(g+f--k&5vlc3wfdrkr*d6wp^y6l3n_v0gutlah8

# Email
DJANGO_EMAIL_USE_SSL=True
DJANGO_EMAIL_HOST='smtp.qq.com'
DJANGO_EMAIL_PORT=25
DJANGO_EMAIL_HOST_USER=''
DJANGO_EMAIL_HOST_PASSWORD=''
DJANGO_DEFAULT_FROM_EMAIL=EMAIL_HOST_USER

# Celery
CELERY_BROKER_URL=redis://127.0.0.1:6379/1
CELERY_RESULT_BACKEND=redis://127.0.0.1:6379/2

# Docker
USE_DOCKER="No"

然后再 base.py 文件 开启读取 .env 环境文件配置:

READ_DOT_ENV_FILE = env.bool("DJANGO_READ_DOT_ENV_FILE", default=True)
if READ_DOT_ENV_FILE:
    # OS environment variables take precedence over variables from .env
    env.read_env(str(BASE_DIR / ".env"))

file

配置 celery 定时任务

celery_app.py 文件添加定时任务 beat任务:

import os

from celery import Celery
from datetime import timedelta

# set the default Django settings module for the 'celery' program.
os.environ.setdefault("DJANGO_SETTINGS_MODULE", "config.settings.local")

app = Celery("tradingbit")

# Using a string here means the worker doesn't have to serialize
# the configuration object to child processes.
# - namespace='CELERY' means all celery-related configuration keys
#   should have a `CELERY_` prefix.
app.config_from_object("django.conf:settings", namespace="CELERY")

# Load task modules from all registered Django app configs.
app.autodiscover_tasks()

# --------------------- 定时任务 ----------------------------------------
# 定义定时任务
app.conf.beat_schedule = {
    'my-task': {
        'task': 'tradingbit.users.tasks.get_users_count',  # 指定任务函数
        'schedule': timedelta(minutes=1),  # 指定任务的执行间隔
    },
}

# 启动celery
# celery -A config.celery_app worker --loglevel=info

# 定时任务执行
# celery -A config.celery_app beat -l info

日志打印:

(tradingbit) ➜  tradingbit git:(develop) ✗ celery -A config.celery_app beat -l info 
celery beat v5.3.1 (emerald-rush) is starting.
__    -    ... __   -        _
LocalTime -> 2023-09-03 02:01:52
Configuration ->
    . broker -> redis://127.0.0.1:6379/1
    . loader -> celery.loaders.app.AppLoader
    . scheduler -> django_celery_beat.schedulers.DatabaseScheduler

    . logfile -> [stderr]@%INFO
    . maxinterval -> 5.00 seconds (5s)
[2023-09-03 02:01:52,724: INFO/MainProcess] beat: Starting...
[2023-09-03 02:01:52,950: INFO/MainProcess] DatabaseScheduler: Schedule changed.
[2023-09-03 02:02:52,951: INFO/MainProcess] Scheduler: Sending due task my-task (tradingbit.users.tasks.get_users_count)
[2023-09-03 02:03:52,976: INFO/MainProcess] Scheduler: Sending due task my-task (tradingbit.users.tasks.get_users_count)

相关文章:
github | cookiecutter-django
Docker 安装 MySQL 和 Redis
cookiecutter-django 文档
Djanngo UsingMySQL

为者常成,行者常至