由DRF上传图片温习到的HTTP知识
在前后端开发的时候,Djangorestframework(简称DRF)是个及其强大的附属于Django的第三方库,依赖于Model的CURD操作大大减少了代码量。之前使用DRF的时候基本都是跟前端json交互,非常容易,但是最近要上传以及跟新图片,遇到了一些小问题,期间不知不觉又拓展到了Http的知识,发现自己有在这方面有些薄弱,温习了一波,特在此记录一波。
1. 熟悉而又陌生的HTTP
某大佬云:学习Web开发不好好学习HTTP报文,将会“打拳不练功,到老一场空”,你花在犯迷糊上的时间比你沉下心来学习HTTP的时间肯定会多很多。
这句话在我看来是及其正确的。作为一个后端开发,不仅仅在于空荡荡地写代码,单身三十年的手速来辅助粘贴,更重要的是在代码有问题进行调试时,了解代码在框架中的运行流程。心中对整个过程了如指掌的程序猿解决问题自然很快,反之,则会花大把时间犯糊涂。
刚实习的那会,大把大把的时间,看过一本思科网络技术学院教程,我是在当当买的,但是听同事说是大学教科书,囧,不过内容古镇的是不错,当时粗粗一读已经解决了大部分心中的疑惑,上网是怎样的过程,TCP/IP啥的。不过还是对细节掌握太少,不然也不会有今日的困惑,乃至回头要重新翻这本书。
教程这里就不说了,网上大把大把,图文并茂,生动地很,这里这是给出链接,自己整理下。
- HTTP状态码
- HTTP请求行、请求头、请求体详解
- HTTP详解(1)-工作原理,当然还有两张图要贴出来方便自己直接看。
一张是TCP/IP模型
另外一张是HTTP协议栈中各层数据流
为什么要贴出来,重要程度就不说了。
2. 让我从DRF瞬移到了HTTP的问题
假设有这样一个Models,
1 |
|
我View视图先按照传统写的,
1 |
|
刚开始没有**parser_classes = (MultiPartParser,)
这一行,而且我的DRF parser 只设置成了'rest_framework.parsers.JSONParser',
,好了找到问题,那我看看哪个合适,FileUploadParser
看上去合适的,设置一下,报错Missing filename. Request should include a Content-Disposition header ....
**
后来看到了解决方法,OK了,但是我对这个**MultiPartParser
很懵逼,FileUploadParser
**不就是上传图片,为何不可行。
其实遇到这个问题也是我设置的问题,DRF默认解析包好了这个MultiPartParser,但我觉得平常只用json,所以只设置成了JSONParser,尴尬,用默认设置即可
3. 使用Django进行文件上传的基础知识
这节的内容翻译自这里
将文件提交到服务器时,文件数据最终会被放入request.FILES。
HTML表单必须使用**enctype=”multipart/form-data”**正确设置属性。否则
request.FILES
将是空的。必须使用POST方法提交表单。
Django有适当的模型字段来处理上传的文件:FileField和ImageField。
上传到FileField或ImageField不存储在数据库中,存储在文件系统中的文件。
FileField和ImageField在数据库中创建为字符串字段(通常为VARCHAR),包含对实际文件的引用。
如果删除包含FileField或ImageField的模型实例,Django将不会删除物理文件,而只会删除对文件的引用。
这request.FILES是一个类字典的对象。request.FILES的键值的名称都是来自
<input type="file" name="" />
。每个值request.FILES都是一个UploadedFile实例。
你将需要设置MEDIA_URL并MEDIA_ROOT在项目的settings.py。
1 |
|
- 在开发服务器中,你可以使用
django.contrib.staticfiles.views.serve()
视图为用户上载的文件(媒体)提供服务。
1 |
|
- 要访问MEDIA_URL模板,你必须添加
django.template.context_processors.media
到您的 context_processeors内部TEMPLATES配置。
4 . multipart/form-data 是什么
整理一下两篇极佳的科普文章:
5. FileUploadParser是什么以及更简单的方式上传图片
FileUploadParser适用于可以将文件作为原始数据请求上载的本机客户端。对于基于Web的上载或具有分段上传支持的本机客户端,应该使用MultiPartParser
**好了,建议是不应该使用 =。= **
其实更好Crete数据的方法还是用DRF的通用视图,贼方便
1 |
|
6. 回过头看看
既然作为一个稳定的web框架,更多的是让开发者方便快速,不用过多地在意包括http以及更多协议中本身繁杂晦涩的概念与操作,封装地很完美,但是很多东西,比如设置文件里仅仅一行字段就能代表很多东西,预留了默认设置,让初学者更加方便快捷,上手即用,没有门槛。但其中很多通用的基础知识在代码运行流程内部体现,需要掌握并且动手不断地尝试,必要时读源码来了解原由。
本博客所有文章除特别声明外,均采用 CC BY-SA 3.0协议 。转载请注明出处!