Django是一个优秀的Python web框架,被众多python开发者所喜爱。新开这个Django专栏,并不是从零开始详细使用Django框架来开发web网页,而是用来开发api。前后分离是当前的技术栈潮流

1.为什么Django中无法像平常一样使用with open 读取静态文件
2.Django实现下载文件功能
3.django非前后分离实现从html页面表单获取输入的数据

1.为什么Django中无法像平常一样使用with open 读取静态文件☆☆☆

  • 一般情况下读取文件:使用with open来打开文件,读取完毕后会自动关闭。文件的相对路径与绝对路径的写法:

    • . 表示文件的当前文件目录
    • .. 表示文件的上一级目录
  • 在Django中读取静态文件完全不同,这是因为框架本身的设计,我们先复习一下之前Django存在多个APP时静态文件的配置

    • 我们的项目有两个 app,分别是 myapp 和 userapp,这样我们的静态文件会分为三部分:
1
2
3
1、公共部分(比如全站都会使用的css、jquery、背景图等)
2、myapp 使用的静态文件
3、userapp 使用的静态文件
  • 在settings.py文件中
1
2
3
4
5
6
7
8
9
10
11
12
13
在 settings.py 中这样设置(三者必不可少):
STATIC_URL = '/static/'
STATIC_ROOT = os.path.join(BASE_DIR, 'static')

# 我们的静态文件分开三个部分
# 这里我们设为三个路径
STATICFILES_DIRS = [
# myproject为主项目的公共静态文件
os.path.join(BASE_DIR, 'myproject', 'static'),
# myapp下的专属静态文件
os.path.join(BASE_DIR, 'myapp', 'static'),
os.path.join(BASE_DIR, 'userapp', 'static'),
]
  • 静态文件加载

注意到,每个 app 中的 static 文件夹内都在包含一个和 app 名称一样的文件夹,在该文件夹内在分别放置各自 css、js、image 等文件夹。 这样做的好处是在部署项目时,执行完 python manage.py collectstatic 命令之后,静态文件被收集到 STATIC_ROOT 之后依旧是根据 app 分开的:
执行collectstatic命令后,最终把静态文件统一集中在主目录下的static文件夹下

PS: 静态文件加载时,都会先去static目录下寻找,如果不存在就继续向下一级,在各个APP的static目录下寻找,一直执行,直到找到为止。

所以我们使用with open访问静态文件就应该为:先访问主static文件,再去APP下寻找

1
2
with open('static/loveword/js/encrypt.js', 'r', encoding='utf-8') as f:
resource1 = f.read()

程序说明,middleware目录下的douyin_parse.py文件想要使用with open读取encrypt.js文件(正常逻辑说是将encrypt文件放在同一目录下,直接就可以读取,但,但是,经过很久的爬坑,发现始终无法读取,一直会报错),Django中只能使用先访问主static文件,再去APP下寻找的方法才能访问到静态文件

2.Django实现下载文件功能

  • urls.py
1
2
3
urlpatterns = [
path('api/deal_zip', views.deal_zip),
]
  • views.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
def deal_zip(req):
# 判断下载文件是否存在
file_path = "static/images/workflow.zip"
if not os.path.isfile(file_path):
return HttpResponse("Sorry but Not Found the File")

def file_iterator(file_path, chunk_size=512):
"""
文件生成器,防止文件过大,导致内存溢出
:param file_path: 文件绝对路径
:param chunk_size: 块大小
:return: 生成器
"""
with open(file_path, mode='rb') as f:
while True:
c = f.read(chunk_size)
if c:
yield c
else:
break

try:
# 设置响应头
# StreamingHttpResponse将文件内容进行流式传输,数据量大可以用这个方法(.pdf,.mp3,.mp4等等什么样格式的文件都可以下载)
response = StreamingHttpResponse(file_iterator(file_path))
# 以流的形式下载文件,这样可以实现任意格式的文件下载
response['Content-Type'] = 'application/octet-stream'
# Content-Disposition就是当用户想把请求所得的内容存为一个文件的时候提供一个默认的文件名
response['Content-Disposition'] = 'attachment;filename={file_name}{format}'.format(
file_name="workflow", format=".zip")
except Exception as e:
return HttpResponse("Sorry but Not Found the File:" + str(e))

# 在这里千万记得return,否则不会出现下载
return response

具体如何实现:用户点击 “下载” 按钮后,就开始下载?

实现起来很简单,用一个a标签,href属性值为Django的url路径,点击a标签后,就会自动下载

1
<h3><span>下载地址:</span><a href="/api/deal_zip"><button>下载</button></a></h3>

3.django非前后分离实现从html页面表单获取输入的数据

参考网址: https://blog.csdn.net/weixin_43424969/article/details/84377955

4.django-rest-framework解析请求参数过程详解

  • request.POST
  • request.GET
  • request.data
  • request.method
  • request.path(表示提交请求页面完整地址的字符串, 不包括域名,如 “/api/music”)
  • request.body(是byte类型,需要使用decode解码成字符串)
  • request.META(包含了所有本次HTTP请求的Header信息)

 评论

联系我 | Contact with me

Copyright © 2019-2020 谁知你知我,我知你知深。此恨经年深,比情度日久

博客内容遵循 署名-非商业性使用-相同方式共享 4.0 国际 (CC BY-NC-SA 4.0) 协议