Django版本1.8.11升级到2.2.6
第一部分:依赖包
Django==2.2.6
mysqlclient==1.4.4
MarkupSafe==1.0
Mako==1.0.6
requests==2.22.0
celery==3.1.25
django-celery==3.2.1
python-json-logger==0.1.7
whitenoise==3.3.0
six==1.11.0
httplib2==0.9.1
由于Django的升级,django restframework也要做出相应的升级(djangorestframework最低3.9.2)
常用的依赖包:
djangorestframework==3.10.3
django-rest-swagger==2.2.0
pypinyin==0.36.0
django-cors-headers==3.2.0
django_extensions==2.2.5
django-filter==2.2.0
第二部分:官方新框架
官方新框架介绍:https://docs.bk.tencent.com/blueapps/USAGE.html
第三部分:djangorestframework的移植
移植djangorestframework:
config/default.py文件内改动
第25行:app注册加入
'rest_test',
'rest_framework',
# swagger
'django_extensions',
'corsheaders',
'django_filters',
'rest_framework_swagger',
第78行:项目路径做出了修改
# # 项目路径
MAKO_TEMPLATE_DIR = [
os.path.join(PROJECT_ROOT, 'templates'),
os.path.join(PROJECT_ROOT, 'static/dist')
]
第155行:文件配置加入:
REST_FRAMEWORK = {
'EXCEPTION_HANDLER': 'component.generics.exception_handler',
'DEFAULT_PERMISSION_CLASSES': (
'rest_framework.permissions.IsAuthenticated',
),
'DEFAULT_PAGINATION_CLASS': 'component.drf.pagination.CustomPageNumberPagination',
'PAGE_SIZE': 10,
# 'DEFAULT_PAGINATION_CLASS': None,
'TEST_REQUEST_DEFAULT_FORMAT': 'json',
'DEFAULT_AUTHENTICATION_CLASSES': (
'rest_framework.authentication.SessionAuthentication',
),
'DEFAULT_FILTER_BACKENDS': ('django_filters.rest_framework.DjangoFilterBackend',),
'DATETIME_FORMAT': "%Y-%m-%d %H:%M:%S"
}
blueapps/conf/default_settings.py文件修改:
第79行TEMPLATES变量加入:os.path.join(PROJECT_ROOT, ‘static/dist’)
TEMPLATES = [
{
'BACKEND': 'django.template.backends.django.DjangoTemplates',
'DIRS': (
os.path.join(BASE_DIR, 'templates'),
os.path.join(PROJECT_ROOT, 'static/dist')
),
'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',
'blueapps.template.context_processors.blue_settings'
],
},
},
{
'BACKEND': 'blueapps.template.backends.mako.MakoTemplates',
'DIRS': (
os.path.join(BASE_DIR, MAKO_DIR_NAME),
),
'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',
'blueapps.template.context_processors.blue_settings'
],
# mako templates cache, None means not using cache
'module_directory': os.path.join(os.path.dirname(BASE_DIR),
'templates_module', APP_CODE)
},
},
]
其次由于djangorestframework版本为3.10.3
语法有所改动:
版本3.6.3:
from rest_framework.decorators import list_route
@list_route(methods=['POST'], url_path='get_list')
版本3.10.3
from rest_framework.decorators import action
@action(methods=["POST"], detail=False, url_path='get_list')
methods: 声明该action对应的请求方式,列表传递
detail: 声明该action的路径是否与单一资源对应,及是否是xxx/{pk}/action方法名/
detail的值有2个:False、True
- True 表示路径格式是xxx/{pk}/action方法名/
- False 表示路径格式是xxx/action方法名/
新框架变动:
- render_json() 改为现在的JsonResponse()
其它更多的变化暂时没用遇到
第四部分:初始化数据到数据库新方法
这里有3种方法:
第一种:写一个初始化数据接口,在项目部署完成,请求接口。
缺点:
- 接口如果发送多次请求,初始化数据会变得糟糕。
- 不方便操作,需要手动初始化。
优点:
- 当项目后台初始化数据通过admin发生变动,项目再进行部署,初始化是可控的。
使用场景: - 初始化的数据,管理员通过后台频繁发生变动
- 初始化的行为操作是可控的
场景样例:初始化数据表的结构频繁发生变动,数据也频繁发生变动,但是初始化的数据是不改变的。
第二种:在app的migrations文件加入初始化数据文件的编写,在初始化表的时候完成数据初始化。总的来说:首次初始化,表字段生成的migration文件要在初始化文件之前。
优点:
- 不需要手动初始化
缺点:
- 对初始化文件的顺序有比较严格的要求。比如一个表2个字段,初始化1条数据(2个字段),这个时候能初始化成功,但后续加入一个时间字段,但时间字段是default,再生成migration文件,进行数据初始化就会报错(首次初始化)。
使用场景:
- 有关数据初始化的表结构不会发生变更或者第一次部署时表字段生成的migration文件要在初始化文件之前。
- 管理员可以频繁通过admin进行修改初始化数据
- 多次部署,只会进行一次初始化。
场景样例1:表结构不会发生变更,管理员会根据市场对后台初始化的数据进行频繁的变更(价钱比较)。
场景样例2:第一次部署完成,数据初始化完成,过了一段时间,有关数据初始化的表结构发生改变(新增了一个字段),新增了一个迁移文件,可以再进行部署,不会进行二次初始化。
第三种:采用信号signals
做一个不恰当的解释:当加载app的时候,读取init文件的配置信息,生成一个或多个相关的信号任务(初始化),在生成表之后,触发一个或多个相关的信号任务。
init.py文件
# -*- coding: utf-8 -*-
default_app_config = 'rest_test.apps.SystemConfig'
apps.py文件
# -*- coding: utf-8 -*-
from __future__ import absolute_import
from django.apps import AppConfig
from django.db.models.signals import post_migrate
import logging
logger = logging.getLogger('rest_rest')
def app_ready_handler(sender=None, **kwargs):
try:
logger.info('初始化数据: start...')
# 初始化指标展示类型
from rest_test.models import TEST
TEST.init_default_data()
logger.info('初始化数据: end...')
except Exception as e:
logger.error('初始化数据失败,原因: %s' % e)
class SystemConfig(AppConfig):
name = 'rest_test'
def ready(self):
post_migrate.connect(app_ready_handler, sender=self)
需要注意的:由于django的版本,init.py文件不允许加入model导入,否则报错 app未加载。
处理:在函数里加入导入model操作
缺点:
- 要求初始化数据不会发生变动,多次部署,数据会多次进行初始化。
优点:
- 不需要手动进行初始化
使用场景:
- 初始化的数据非常稳定,admin后台中初始化的数据不会发生变动。
- 表结构不是很稳定,会发生变动,生成新的迁移文件。
场景样例:有一张药品组成的信息表,组成信息基本不会发生变动,但后续加入了一个发明时间字段。