环境
mkvirtualenv -p python3.6 mytest # 创建虚拟环境
workon mytest # 进入虚拟环境
# 按照基础环境依赖
pip install django==1.11.11
pip install djangorestframework
pip install pymysql
创建项目
"""
前提:在目标目录新建 mytest 文件夹
>: cd 建立的 mytest 文件夹
>: django-admin startproject mytest
开发:用pycharm打开项目,并选择提前备好的虚拟环境
"""
重构项目目录
"""
├── mytest
├── logs/ # 项目运行时/开发时日志目录 - 文件夹
├── manage.py # 脚本文件
├── mytest/ # 项目主应用,开发时的代码保存 - 包
│ ├── apps/ # 开发者的代码保存目录,以模块[子应用]为目录保存 - 包
│ ├── libs/ # 第三方类库的保存目录[第三方组件、模块] - 包
│ ├── settings/ # 配置目录 - 包
│ ├── dev.py # 项目开发时的本地配置
│ ├── prod.py # 项目上线时的运行配置
│ ├── urls.py # 总路由
│ ├── utils/ # 多个模块[子应用]的公共函数类库[自己开发的组件]
└── scripts/ # 保存项目运营时的脚本文件 - 文件夹
"""
配置开发环境
"""
1.修改 wsgi.py 与 manage.py 两个文件:
os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'mytest.settings.dev')
2.将settings.py删除或改名,内容拷贝到settings/dev.py中
3.修改dev.py文件内容
LANGUAGE_CODE = 'zh-hans'
TIME_ZONE = 'Asia/Shanghai'
4.修改启动配置:见插图
https://i.loli.net/2019/09/30/nyT21dIvRjpzVGM.png
5.在任何一个__init__.pu文件中测试默认配置文件是否是dev.py文件
from django.conf import settings
print(settings)
"""
配置日志
# 官网:https://docs.djangoproject.com
# 中文loggin配置:https://docs.djangoproject.com/zh-hans/2.2/topics/logging/
# 在项目的 dev.py 中配置 Django 项目的log日志,那Django自己出现的打印记录不仅可以输出到控制台,还可以记录到日志文件,当项目上线记录日志时及其重要的
LOGGING = {
'version': 1,
'disable_existing_loggers': False,
'formatters': {
'verbose': {
'format': '%(levelname)s %(asctime)s %(module)s %(lineno)d %(message)s'
},
'simple': {
'format': '%(levelname)s %(module)s %(lineno)d %(message)s'
},
},
'filters': {
'require_debug_true': {
'()': 'django.utils.log.RequireDebugTrue',
},
},
'handlers': {
'console': {
'level': 'DEBUG',
'filters': ['require_debug_true'],
'class': 'logging.StreamHandler',
'formatter': 'simple'
},
'file': {
# 实际开发建议使用WARNING
'level': 'INFO',
'class': 'logging.handlers.RotatingFileHandler',
# 日志位置,日志文件名,日志保存目录必须手动创建,注:这里的文件路径要注意BASE_DIR
'filename': os.path.join(os.path.dirname(BASE_DIR), "logs/luffy.log"),
# 日志文件的最大值,这里我们设置300M
'maxBytes': 300 * 1024 * 1024,
# 日志文件的数量,设置最大日志数量为10
'backupCount': 10,
# 日志格式:详细格式
'formatter': 'verbose',
'encoding': 'utf-8'
},
},
# 日志对象
'loggers': {
'django': {
'handlers': ['console', 'file'],
'propagate': True, # 是否让日志信息继续冒泡给其他的日志处理系统
},
}
}
数据库配置
"""
1.管理员连接数据库
2.创建数据库
>: create database mytest default charset=utf8;
3.以管理员身份登录数据库
>: mysql -uroot -p123
4.查看用户
>: select user,host,password from mysql.user;
5.设置权限账号密码
# 授权账号命令:grant 权限(create, update) on 库.表 to '账号'@'host' identified by '密码'
>: grant all privileges on mytest.* to 'mytest'@'%' identified by 'mytest';
# 要是本机连mysql连不上,再添加localhost访问权限,本机就可以登录了
>: grant all privileges on mytest.* to 'mytest'@'localhost' identified by 'mytest';
# 设置完有权限限制的账号后一定要刷新权限,如果没刷新权限,该终端无法被通知
>: flush privileges;
6.退出管理员,用账号 mytest 密码 mytest 登入开发
>: exit
>: mysql -umytest -pmytest
# 后台项目进行数据库配置
7.mytest/settings.py配置
DATABASES = {
"default": {
"ENGINE": "django.db.backends.mysql",
"HOST": "127.0.0.1",
"PORT": 3306,
"USER": "mytest",
"PASSWORD": "mytest",
"NAME": "mytest",
}
}
6.mytest/__init__.py
import pymysql
pymysql.install_as_MySQLdb()
7.运行会出现Django与pymysql版本兼容问题:见两张插图
"""
home应用的创建
注册drf、弃用jdango的csrf
# dev.py
INSTALLED_APPS = [
# ...
'rest_framework',
]
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',
]
创建 home 应用
"""
1.前往apps目录下创建app:cd mytest/apps
2.创建app:python ../../manage.py startapp home
"""
配置 apps 到环境变量并注册home应用
# dev.py
import os
import sys
BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
sys.path.append(os.path.join(BASE_DIR, 'apps'))
# 注:不添加环境变量,注册 应用 很麻烦,会出现 应用 找不到
INSTALLED_APPS = [
# ...
'home'
]
注册子路由
# 主路由:urls.py
from django.conf.urls import url, include
urlpatterns = [
# ...
url('', include('home.urls')),
]
# 子路由:home/urls.py
from django.conf.urls import url
urlpatterns = [
]
分离的前后台交互
后台处理跨域
'''
https://github.com/ottoyiu/django-cors-headers/
安装django-cors-headers模块
在settings.py中配置
# 注册app
INSTALLED_APPS = [
...
'corsheaders'
]
# 添加中间件
MIDDLEWARE = [
...
'corsheaders.middleware.CorsMiddleware'
]
# 允许跨域源
CORS_ORIGIN_ALLOW_ALL = False
# 配置指定跨域域名
CORS_ORIGIN_WHITELIST = [
'http://example.com'
]
# 允许ajax请求携带cookie
CORS_ALLOW_CREDENTIALS = True
# 注:前台请求头携带参数,中间件拒绝Access-Control-Allow-Headers错误,中间件要设置 default_headers
from corsheaders import defaults
在 default_headers 中添加 '前端ajax请求头里面的字段名'
'''
静态目录
# dev.py 配置
# 1.访问静态文件的url地址前缀
STATIC_URL = '/static/'
# 2. 设置django的静态文件目录
STATICFILES_DIRS = [
os.path.join(BASE_DIR, "static")
]
# 静态目录创建
# 3.在luffyapi/luffyapi中创建static目录(谁是项目根目录就在那个文件夹下创建)
媒体目录
# dev.py配置
# 1.访问上传文件的url地址前缀
MEDIA_URL = "/media/"
# 2.项目中存储上传文件的根目录
MEDIA_ROOT = os.path.join(BASE_DIR, "media")
# 媒体目录创建
# 3.在luffyapi/luffyapi中创建media目录(谁是项目根目录就在那个文件夹下创建)
# 配置路由
from django.urls import re_path
from django.views.static import serve
from django.conf import settings
urlpatterns = [
re_path(r'media/(?P<path>.*)', serve, {"document_root": settings.MEDIA_ROOT}),
]
drf-jwt开发
配置信息:JWT_AUTH到dev.py中
import datetime
JWT_AUTH = {
# 过期时间
'JWT_EXPIRATION_DELTA': datetime.timedelta(days=1), # hours 小时、minutes 分钟
# 自定义认证结果:见下方序列化user和自定义response
'JWT_RESPONSE_PAYLOAD_HANDLER': 'home.utils.jwt_response_payload_handler',
}
自定义response:home/utils.py
def jwt_response_payload_handler(token, user=None, request=None):
# restful 规范
return {
'code': 0,
'msg': 'OK',
'data': {
'token': token,
'username': user.username
}
}
基于drf-jwt的全局认证:home/authentications.py(自己创建)
import jwt
from rest_framework.exceptions import AuthenticationFailed
from rest_framework_jwt.authentication import jwt_decode_handler
from rest_framework_jwt.authentication import get_authorization_header
from rest_framework_jwt.authentication import BaseJSONWebTokenAuthentication
class JSONWebTokenAuthentication(BaseJSONWebTokenAuthentication):
def authenticate(self, request):
# 采用drf获取token的手段 - HTTP_AUTHORIZATION - Authorization
token = get_authorization_header(request)
if not token:
raise AuthenticationFailed('Authorization 字段是必须的')
# 可以添加反扒措施:原功能是token有前缀
# drf-jwt认证校验算法
try:
payload = jwt_decode_handler(token)
except jwt.ExpiredSignature:
raise AuthenticationFailed('签名过期')
except jwt.InvalidTokenError:
raise AuthenticationFailed('非法用户')
user = self.authenticate_credentials(payload)
# 将认证结果丢该drf
return user, token
全局启用:settings/dev.py
REST_FRAMEWORK = {
# 认证模块
'DEFAULT_AUTHENTICATION_CLASSES': (
'home.authentications.JSONWebTokenAuthentication',
),
}
局部启用禁用:任何一个cbv类首行
# 局部禁用
authentication_classes = []
# 局部启用
from home.authentications import JSONWebTokenAuthentication
authentication_classes = [JSONWebTokenAuthentication]
数据库迁移、超级管理员
'''
数据库迁移:python manage.py makemigrations
python manage.py migrate
创建超级管理员:python manage.py createsuperuser
'''