diff --git "a/Day41-55/52.\346\216\245\345\205\245\344\270\211\346\226\271\345\271\263\345\217\260.md" "b/Day41-55/52.\346\216\245\345\205\245\344\270\211\346\226\271\345\271\263\345\217\260.md"
index 9460cd7fcc75d5f0bf1b533ecd508a1361539a73..b6094cf7258279bd994ff40b6cd7de3acf68d7fe 100644
--- "a/Day41-55/52.\346\216\245\345\205\245\344\270\211\346\226\271\345\271\263\345\217\260.md"
+++ "b/Day41-55/52.\346\216\245\345\205\245\344\270\211\346\226\271\345\271\263\345\217\260.md"
@@ -100,3 +100,102 @@ def get_mobilecode(request, tel):
### 接入云存储服务
+当我们提到**云存储**这个词的时候,通常是指把数据存放在由第三方提供的虚拟服务器环境下,简单的说就是将某些数据或资源通过第三平台托管。一般情况下,提供云存储服务的公司都运营着大型的数据中心,需要云存储服务的个人或组织通过向其购买或租赁存储空间来满足数据存储的需求。在开发Web应用时,可以将静态资源,尤其是用户上传的静态资源直接置于云存储服务中,云存储通常会提供对应的URL使得用户可以访问该静态资源。国内外比较有名的云存储服务(如:亚马逊的S3、阿里的OSS2等)一般都物美价廉,相比自己架设静态资源服务器,云存储的代价更小,而且一般的云存储平台都提供了CDN服务,用于加速对静态资源的访问,所以不管从哪个角度出发,使用云存储的方式管理Web应用的数据和静态资源都是非常好的选择,除非这些资源涉及到个人或商业隐私,否则就可以托管到云存储中。
+
+下面我们以接入[七牛云](https://www.qiniu.com/)为例,讲解如何实现将用户上传的文件保存到七牛云存储。七牛云是国内知名的云计算及数据服务提供商,七牛云在海量文件存储、CDN、视频点播、互动直播以及大规模异构数据的智能分析与处理等领域都有自己的产品,而且非付费用户也可以免费接入,使用其提供的服务。下面是接入七牛云的流程:
+
+1. 注册账号,登录管理控制台。
+
+ ![](res/qiniu-manage-console.png)
+
+2. 选择左侧菜单中的对象存储。
+
+ ![](res/qiniu-storage-service.png)
+
+3. 在空间管理中选择新建空间(例如:myvote),如果提示空间名称已被占用,更换一个再尝试即可。注意,创建空间后会提示绑定自定义域名,如果暂时还没有自己的域名,可以使用七牛云提供的临时域名,但是临时域名会在30天后被回收,所以最好准备自己的域名(域名需要备案,不清楚如何操作的请自行查阅相关资料)。
+
+ ![](res/qiniu-storage-create.png)
+
+4. 在网页的右上角点击个人头像中的“密钥管理”,查看自己的密钥,稍后在代码中需要使用AK(AccessKey)和SK(SecretKey)两个密钥来认证用户身份。
+
+ ![](res/qiniu-secretkey-management.png)
+
+5. 点击网页上方菜单中的“文档”,进入到[七牛开发者中心](https://developer.qiniu.com/),选择导航菜单中的“SDK&工具”并点击“官方SDK”子菜单,找到Python(服务端)并点击“文档”查看官方文档。
+
+ ![](res/qiniu-document-python.png)
+
+接下来,只要安装官方文档提供的示例,就可以接入七牛云,使用七牛云提供的云存储以及其他服务。首先可以通过下面的命令安装七牛云的三方库。
+
+```Bash
+pip install qiniu
+```
+
+接下来可以通过`qiniu`模块中的`put_file`和`put_stream`两个函数实现文件上传,前者可以上传指定路径的文件,后者可以将内存中的二进制数据上传至七牛云,具体的代码如下所示。
+
+```Python
+import qiniu
+
+AUTH = qiniu.Auth('密钥管理中的AccessKey', '密钥管理中的SecretKey')
+BUCKET_NAME = 'myvote'
+
+
+def upload_file_to_qiniu(key, file_path):
+ """上传指定路径的文件到七牛云"""
+ token = AUTH.upload_token(BUCKET_NAME, key)
+ return qiniu.put_file(token, key, file_path)
+
+
+def upload_stream_to_qiniu(key, stream, size):
+ """上传二进制数据流到七牛云"""
+ token = AUTH.upload_token(BUCKET_NAME, key)
+ return qiniu.put_stream(token, key, stream, None, size)
+```
+
+下面是一个文件上传的简单前端页。
+
+```HTML
+
+
+
+
+ 上传文件
+
+
+
+
+
+```
+
+> **说明**:前端如果使用表单实现文件上传,表单的method属性必须设置为post,enctype属性需要设置为multipart/form-data,表单中type属性为file的input标签,就是上传文件的文件选择器。
+
+实现上传功能的视图函数如下所示。
+
+```Python
+from django.views.decorators.csrf import csrf_exempt
+
+
+@csrf_exempt
+def upload(request):
+ # 如果上传的文件小于2.5M,则photo对象的类型为InMemoryUploadedFile,文件在内存中
+ # 如果上传的文件超过2.5M,则photo对象的类型为TemporaryUploadedFile,文件在临时路径下
+ photo = request.FILES.get('photo')
+ _, ext = os.path.splitext(photo.name)
+ # 通过UUID和原来文件的扩展名生成独一无二的新的文件名
+ filename = f'{uuid.uuid1().hex}{ext}'
+ # 对于内存中的文件,可以使用上面封装好的函数upload_stream_to_qiniu上传文件到七牛云
+ # 如果文件保存在临时路径下,可以使用upload_file_to_qiniu实现文件上传
+ upload_stream_to_qiniu(filename, photo.file, photo.size)
+ return redirect('/static/html/upload.html')
+```
+
+> **注意**:上面的视图函数使用了`csrf_exempt`装饰器,该装饰器能够让表单免除必须提供CSRF令牌的要求。此外,代码第11行使用了`uuid`模块的`uuid1`函数来生成全局唯一标识符。
+
+运行项目尝试文件上传的功能,文件上传成功后,可以在七牛云“空间管理”中点击自己空间并进入“文件管理”界面,在这里可以看到我们刚才上传成功的文件,而且可以通过七牛云提供的域名获取该文件。
+
+![](res/qiniu-file-management.png)
+
diff --git a/Day41-55/res/qiniu-document-python.png b/Day41-55/res/qiniu-document-python.png
new file mode 100644
index 0000000000000000000000000000000000000000..dbfc9261ebb1e66c7db11898603e97776fbe0279
Binary files /dev/null and b/Day41-55/res/qiniu-document-python.png differ
diff --git a/Day41-55/res/qiniu-file-management.png b/Day41-55/res/qiniu-file-management.png
new file mode 100644
index 0000000000000000000000000000000000000000..c288b7f0fcfe8cb9f4d150c571ad2047283a6f3d
Binary files /dev/null and b/Day41-55/res/qiniu-file-management.png differ
diff --git a/Day41-55/res/qiniu-manage-console.png b/Day41-55/res/qiniu-manage-console.png
new file mode 100644
index 0000000000000000000000000000000000000000..0d44a6fad1cfc6acac799e414682b38032e763ba
Binary files /dev/null and b/Day41-55/res/qiniu-manage-console.png differ
diff --git a/Day41-55/res/qiniu-secretkey-management.png b/Day41-55/res/qiniu-secretkey-management.png
new file mode 100644
index 0000000000000000000000000000000000000000..c1de7ad373e6e0c930560cb35b97240a3f396608
Binary files /dev/null and b/Day41-55/res/qiniu-secretkey-management.png differ
diff --git a/Day41-55/res/qiniu-storage-create.png b/Day41-55/res/qiniu-storage-create.png
new file mode 100644
index 0000000000000000000000000000000000000000..b459e3760ed7f3966c2d62eaf36f2174803124a5
Binary files /dev/null and b/Day41-55/res/qiniu-storage-create.png differ
diff --git a/Day41-55/res/qiniu-storage-service.png b/Day41-55/res/qiniu-storage-service.png
new file mode 100644
index 0000000000000000000000000000000000000000..6844e3bdd68f55bacc61c85081b267e8a824581b
Binary files /dev/null and b/Day41-55/res/qiniu-storage-service.png differ