一.配置注意项
1.使用MySQL之前,要在项目中配置MySQL驱动:
import pymysql
pymysql.install_as_MySQLdb()
2.配置redis数据库存储session:
CACHES = {
"session": { # session的容器
"BACKEND": "django_redis.cache.RedisCache",
"LOCATION": "redis://10.211.55.5:6379/0",
"OPTIONS": {
"CLIENT_CLASS": "django_redis.client.DefaultClient",
}
},
}
# 将项目中的session存储到redis中
SESSION_ENGINE = "django.contrib.sessions.backends.cache"
SESSION_CACHE_ALIAS = "session"
3.日志配置:
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在debug模式下才输出日志
'()': 'django.utils.log.RequireDebugTrue',
},
},
'handlers': { # 日志处理方法
'console': { # 向终端中输出日志
'level': 'INFO',
'filters': ['require_debug_true'],
'class': 'logging.StreamHandler',
'formatter': 'simple'
},
'file': { # 向文件中输出日志
'level': 'INFO',
'class': 'logging.handlers.RotatingFileHandler',
# 日志文件的位置
'filename': os.path.join(os.path.dirname(BASE_DIR), "logs/meiduo.log"),
'maxBytes': 300 * 1024 * 1024, # 日志文件的最大容量 300M
'backupCount': 10, # 300M * 10
'formatter': 'verbose'
},
},
'loggers': {
'django': { # 定义了一个名为django的日志器
'handlers': ['console', 'file'], # 可以同时向终端与文件中输出日志
'level': 'INFO', # 日志器接收的最低日志级别
},
}
}
二.celery(三部分:brocker和worker和task result store)
1.在celery包中创建main.py,在main.py文件中创建celery应用,并将含有任务的文件路径添加到celery.autodiscover_tasks('celery_tasks.sms'),扫描才能找到;
2.在任务文件中创建tasks.py(固定的名称),创建任务(被celery应用.task装饰之后才为celery应用)
3.由于任务的执行同主程序分开,如果主程序想获取任务执行的结果,就必须通过中间件存储。
三.JWT(Header Payload Signature-用script-key加密,不需要自己加密和验证,只需要返回token)的使用流程:
1.后台生成jwt:使用第三方库djangorestframework-jwt生成JWT(手动添加认证方式)
2.前端保存JWT:前段通过localStorage或sessionStorage来保存JWT
3.通过请求头上传JWT:axios.get('url', config)
4.校验JWT:
在项目配置文件中,配置djangorestframework-jwt提供的JWT认证类,会自动对请求的jwt进行校验,通过后,在django的视图中,可以通过
request.user验证能够登录的用户.
5.# 接收生成payload函数(user)
jwt_payload_handler = api_settings.JWT_PAYLOAD_HANDLER
# 接收生成JWT函数(payload)
jwt_encode_handler = api_settings.JWT_ENCODE_HANDLER
四.QQ登录(outh2.0:要获得应用生产openid,每个QQ号对应一个openid)
1. 显示QQ登录界面
2. 准备回调界面,获取code(QQ后台会自动发送)参数
3. 实现QQ认证接口:
(1) 根据code获取access_token
(2) 根据access_token获取opendid
(3) 根据opendid,从映射表查询美多用户
- 如果能查询到美多用户,则生成响应jwt,user_id,username, 完成QQ登陆流程
- 如果不能查询到美多用户,则返回opendid,等待用户后续的绑定操作
4. 绑定opendid和美多用户
五.itsdangerous加密(加密解密都要取得应用,秘钥为secre-key(需要制定))
1.安装: pip install itsdangerous
2.使用 TimedJSONWebSignatureSerializer 可以生成带有有效期的加密数据
-创建: TimedJSONWebSignatureSerializer(密钥, 有效期秒)
-签名: dumps(dict) 返回bytes类型数据(jwt字符串)
-验签: loads(str) 返回字典
- 可以确保没有被篡改
- 数据会过期
- 解密出错异常
- BadData 父类
- SignatureExpired: 签名过期
- BadSignature: 要解密的数据被篡改
六.邮箱激活
1.163邮箱设置;
2.django项目配置:
EMAIL_BACKEND = 'django.core.mail.backends.smtp.EmailBackend'
EMAIL_HOST = 'smtp.163.com'
EMAIL_PORT = 25
#发送邮件的邮箱
EMAIL_HOST_USER = 'itcast88@163.com'
#在邮箱中设置的客户端授权密码
EMAIL_HOST_PASSWORD = 'python808'
#收件人看到的发件人
EMAIL_FROM = 'python<itcast88@163.com>'
3.激活流程:
1.发送激活连接到邮箱:
send_mail(subject, message, from_email, recipient_list,html_message=None)
subject 邮件标题
message 普通邮件正文, 普通字符串
from_email 发件人
recipient_list 收件人列表
html_message 多媒体邮件正文,可以是html字符串
2.点击链接在mounted中发送连接:
1.获取token
2.校验token的合法性(Timed...)
3.从token中获取user_id和email
4.查询用户对象是否已激活
5.给用户激活邮箱
6.返回验证成功
http://www.meiduo.site:8080/success_verify_email.html?token=eyJhbGciOiJIUzUxMiIsImV4cCI6MTU0NzIwNzEyMiwiaWF0IjoxNTQ3MTIwNzIyfQ.eyJ1c2VyX2lkIjoxLCJlbWFpbCI6Iml0X3ptekAxNjMuY29tIn0.xwPHQLOv2IQI-MOQ5PhyD8iRhqmUJmVJJ3I8WB4v1TEpO--iv2OBV8dsCMVp8v4fKP1O7sOrVyuCWoYV--XsXA
data = {'user_id': self.id, 'email': self.email}
七.给视图添加缓存(表的数据不经常改变):pip install drf-extensions
1.继承对应的缓存扩展类
1. ListCacheResponseMixin
- 实际是为list方法添加了cache_response装饰器
2. RetrieveCacheResponseMixin
- 实际是为retrieve方法添加了cache_response装饰器
3. CacheResponseMixin
为视图集同时补充List和Retrieve两种缓存,与ListModelMixin和RetrieveModelMixin一起配合使用。
2.在配置文件中指定缓存过期时间
REST_FRAMEWORK_EXTENSIONS = {
'DEFAULT_CACHE_RESPONSE_TIMEOUT': 60 * 60, # 缓存时间,单位秒
'DEFAULT_USE_CACHE': 'default', # 缓存存储缓存到哪里 (redis)
}
八.FastDFS分布式文件系统(文件去重(扫描文件内容,而不是文件名),海量存储,文件备份)
- 开源的分布式文件存储系统,可以实现包括 文件存储、文件上传、文件下载, 文件同步等功能;
- 应用场景:适合以文件为载体的在线服务,如相册网站、视频网站等
第一部分:Tracker Server: '跟踪服务器',调度服务器
作用:调度,在文件上传时,`Tracker Server`会找到 `Storage server`,提供文件上传服务
第二部分:Storage server: '存储服务器'
作用: 存储文件
可以集群,分成多个组,每个组又有多台服务器
不同的组保存的文件不同;
同一个组内的多台服务器保存的文件相同,起到文件备份的作用;
同一个组每台服务器地位平等,没有主从的概念
文件上传到FastDFS成功后,服务器会返回一个文件路径,型如:
group1/M00/00/00/wKjSnFpxjn2Aeds7AAfKM6ERqQA402
组名/虚拟磁盘路径/一级目录/二级目录/文件名
九.docker(是一个客户端-服务器(C/S)架构程序)使用
打包应用及其依赖包到容器中,从而可以将应用快速地部署到任意的Linux系统上。
- 隔离环境
- 性能开销低,启动速度快
1.安装:
sudo apt-key add gpg
sudo dpkg -i docker-ce_17.03.2~ce-0~ubuntu-xenial_amd64.deb # 老师资料中提供的安装包
2.开启与关闭
# 启动docker
sudo service docker start
# 停止docker
sudo service docker stop
# 重启docker
sudo service docker restart
3.镜像操作
# 一、列出镜像
sudo docker image ls
# 二、加载镜像
# 1.拉取官方的镜像 (Docker官方提供的镜像,都放在默认的组library中,可以省略)
sudo docker image pull library/hello-world
sudo docker image pull hello-world
# 2.加载本地镜像
sudo docker load -i ./ubuntu.tar
sudo docker load -i fastdfs_docker.tar
# 三、删除镜像 (没有创建容器的镜像才可以删)
sudo docker image rm 镜像名或镜像id
例: sudo docker image rm hello-world
4.容器操作
一、创建容器(根据镜像运行容器)
sudo docker run [option] 镜像名:TAG [向启动容器中传入的命令] # 说明 :TAG 部分可以省略
# 示例1:创建交互式容器
sudo docker run -it --name=myubuntu ubuntu /bin/bash
# 示例2:创建守护式容器
sudo docker run -dit --name=myubuntu2 ubuntu
常用可选参数说明:
--name 为创建的容器命名
-i 表示以“交互模式”运行容器 --interactive
-t 表示容器启动后会进入其命令行。常与-i连用,加入这两个参数后,容器创建就能进入容器
-d Run container in background and print container ID --detach 解绑
守护式容器,后台运行,而不会自动进入容器(命令行);
如果只加-i -t 两个参数,创建后就会自动进入容器(命令行)
-v 目录映射关系,使用格式: 宿主机目录:容器中目录,可以使用多个-v做多个目录或文件映射 --volume
注意: 最好做目录映射,在宿主机上做修改,然后共享到容器上。
--network=host 表示将主机的网络环境映射到容器中,容器的网络与主机相同
-p 表示端口映射,前者是宿主机端口,后者是容器内的映射端口。可以使用多个-p 做多个端口映射
-e 为容器设置环境变量
二、查看容器
# 列出本机正在运行的容器
sudo docker container ls
# 列出本机所有容器,包括已经终止运行的
sudo docker container ls --all
三、启动和停止容器
# 启动一个已经停止的容器
sudo docker container start 容器名或容器id
# 停止一个已经在运行的容器
sudo docker container stop 容器名或容器id
# 杀掉一个已经在运行的容器
sudo docker container kill 容器名或容器id
四.将容器转换为镜像保存
sudo docker commit 容器名 镜像名
五.将镜像备份迁移
sudo docker save -o 保存的文件名 镜像名
另外一台电脑上打开:
sudo docker load -i 保存的文件名
十.FastDFS客户端
1.安装
pip install fdfs_client-py-master.zip
pip install mutagen
pip isntall requests
2.配置
# 指定使用自定义的文件存储类
DEFAULT_FILE_STORAGE = 'meiduo_mall.utils.fastdfs.storage.FastDFSStorage'
2.使用(FastDFSStorage:继承FileSystemStorage,重写_save方法和url(返回值会自动保存到数据库)方法)
client = Fdfs_client('meiduo_mall/utils/fastdfs/client.conf') 获取应用
dict_data = client.upload_by_buffer(content.read()) 上传的结果
十一.CKEditor基本使用
1. 安装: pip install django-ckeditor
2. 在settings/dev.py中配置文件中注册应用
INSTALLED_APPS = [
...
'ckeditor', # 富文本编辑器
'ckeditor_uploader', # 富文本编辑器上传图片模块
]
3. 添加CKEditor设置
# dev.py
# 富文本编辑器ckeditor配置
CKEDITOR_CONFIGS = {
'default': {
'toolbar': 'full', # 工具条功能
'height': 300, # 编辑器高度
# 'width': 300, # 编辑器宽
},
}
# 上传图片保存的路径,使用了FastDFS后,此路径用不到
CKEDITOR_UPLOAD_PATH = 'uploads/'
4. 添加ckeditor路由,在根路由中添加
# meiduo_mall/urls.py
url(r'^ckeditor/', include('ckeditor_uploader.urls')),
5. 为 商品模型类 的三个字段 使用富文本编辑器类型
ckeditor提供了两种类型的Django模型类字段:
RichTextField 不支持上传文件的富文本字段
RichTextUploadingField 支持上传文件的富文本字段
# goods/models.py
class Goods(BaseModel):
"""商品SPU"""
...
# 在商品模型类(SPU)中,要保存商品的详细介绍、包装信息、售后服务,这三个字段修改为富文本类型
desc_detail = RichTextUploadingField(default='', verbose_name='详细介绍')
desc_pack = RichTextField(default='', verbose_name='包装信息')
desc_service = RichTextUploadingField(default='', verbose_name='售后服务')
6. 重新迁移生成数据库表
十二.页面静态化(查询出数据,模板语法添加到html,将文件写到对应位置)
template = loader.get_template('index.html') # 在template文件夹中获取静态文件
html_text = template.render(context) # 加载数据(bytes)
file_path = os.path.join(settings.GENERATED_STATIC_HTML_FILES_DIR, 'index.html') # 确定目标文件路径
with open(file_path, 'w', encoding='utf-8') as f: # 写入文件
f.write(html_text)
十三.定时任务
1.安装:pip install django-crontab
2.添加应用: 'django_crontab'
3.设置定时任务
CRONJOBS = [
# 每5分钟执行一次生成主页静态文件
('*/5 * * * *', 'contents.crons.generate_static_index_html', '>> /Users/delron/Desktop/meiduo_mall/logs/crontab.log')
]
4.解决crontab中文问题
CRONTAB_COMMAND_PREFIX = 'LANG_ALL=zh_cn.UTF-8'
5.任务操作
添加定时任务到系统中
python manage.py crontab add
显示已经激活的定时任务
python manage.py crontab show
移除定时任务
python manage.py crontab remove
十四.触发生成静态页面
class GoodsCategoryAdmin(admin.ModelAdmin):
def save_model(self, request, obj, form, change):
obj.save()
from celery_tasks.html.tasks import generate_static_list_search_html
generate_static_list_search_html.delay()
def delete_model(self, request, obj):
obj.delete()
from celery_tasks.html.tasks import generate_static_list_search_html
generate_static_list_search_html.delay()
admin.site.register(models.GoodsCategory, GoodsCategoryAdmin)
十五.ElasticSearch索引库创建
Databases(数据库) <-> Tables (模型类)
Indices(索引库) <-> Types (索引类)
1.使用docker安装ElasticSearch
(1). 加载提供给大家的镜像文件
sudo docker load -i elasticsearch-ik-2.4.6_docker.tar
(2). 把资料中提供的 elasticsearch 配置文件复制到 ubuntu home目录,并作如下修改:
elasticsearc-2.4.6/config/elasticsearch.yml 第54行,更改ip地址为ubuntu的ip地址
network.host: 192.168.210.160
(3). 通过镜像运行elasticsearch容器
sudo docker run -dti --network=host --name=elasticsearch -v /home/python/elasticsearch-2.4.6/config:/usr/share/elasticsearch/config delron/elasticsearch-ik:2.4.6-1.0
(4). 测试 ElasticSearch 是否安装成功
sudo apt install curl
curl 'http://192.168.210.160:9200/'
看到类似如下图的返回结果,说明elasticsearch安装成功,并且elasticsearch服务器端已经启动起来。
2.安装媒介Haystack
(1). 安装python包
# pip install django-haystack
pip install drf-haystack
pip install elasticsearch==2.4.1
(2). 注册应用
INSTALLED_APPS = [
...
'haystack',
...
]
(3). 在项目的配置文件中配置haystack
# dev.py 配置haystack全文检索框架
HAYSTACK_CONNECTIONS = {
'default': {
'ENGINE': 'haystack.backends.elasticsearch_backend.ElasticsearchSearchEngine',
# 此处为elasticsearch运行的服务器ip地址,端口号默认为9200
'URL': 'http://192.168.210.160:9200/',
# 指定elasticsearch建立的索引库的名称
'INDEX_NAME': 'meiduo',
},
}
# 当添加、修改、删除数据时,自动更新索引
HAYSTACK_SIGNAL_PROCESSOR = 'haystack.signals.RealtimeSignalProcessor'
3.在search_indexes.py(名字固定)中创建索引类:
(1)特殊字段:
text = indexes.CharField(document=True, use_template=True),通过他来搜索,其他字段来自于模型类
(2)两个特殊函数:
def get_model(self):
"""返回建立索引的模型类"""
return SKU
def index_queryset(self, using=None):
"""返回要建立索引的数据查询集"""
return self.get_model().objects.filter(is_launched=True)
4.模板文件
templates/search/indexes/goods/sku_text.txt # 路径和名字固定, 否则报错如下
{{ object.name }}
{{ object.caption }}
{{ object.id }}
5.运行创建ES索引库
python manage.py rebuild_index
十六.ElasticSearch使用
1.序列化器:
from drf_haystack.serializers import HaystackSerializer
class SKUIndexSerializer(HaystackSerializer):
"""
SKU索引结果数据序列化器
"""
class Meta:
index_classes = [SKUIndex]
fields = ('text', 'id', 'name', 'price', 'default_image_url', 'comments')
2.视图:
from drf_haystack.viewsets import HaystackViewSet
class SKUSearchViewSet(HaystackViewSet):
"""
SKU搜索
HaystackViewSet: 查一条,查多条
"""
index_models = [SKU]
serializer_class = SKUIndexSerializer
十七.支付宝:(传入公钥和私钥创建应用,RSA2加密)第三方SDK
传回来的参数自己验证
获取alipay应用
alipay = AliPay(
appid=settings.ALIPAY_APPID,
app_notify_url='http://www.meiduo.site/pay_success.html', # 默认回调url(确认订单自己调用)
app_private_key_string=app_private_key_string,
# 支付宝的公钥,验证支付宝回传消息使用,不是你自己的公钥,
alipay_public_key_string=alipay_public_key_string,
sign_type="RSA2", # RSA 或者 RSA2
debug=settings.ALIPAY_DEBUG
)
success = alipay.verify(data, signature)
十八.mysql主从配置
将主数据库的内容添加到从数据库:
mysqldump -uroot -pmysql --all-databases --lock-all-tables > ~/master_db.sql
mysql -uroot -pmysql -h127.0.0.1 --port=8306 < ~/master_db.sql
主服务器:
开启二进制日志
配置唯一的server-id
获得master二进制日志文件名及位置
创建一个用于slave和master通信的用户账号
从服务器:
配置唯一的server-id
使用master分配的用户账号读取master二进制日志
启用slave服务