对于上传的文件,MultiPartParser class本身没有具体的逻辑,而是提供了一套处理机制,由提供的实现 class FileUploadHandler 的类完成处理。可以提供多个handler,通过参数 settings.FILE_UPLOAD_HANDLERS 配置,有默认值,参考文档:link。这些handler会对每一个Request初始化一次,然后使用同一个handler instance处理request内所有的文件上传信息,根据代码Django遵循了POST数据内每一个 form field or file chunk 都是顺序连续出现的,不会有交叉。 MultiPartParser循环读取上传文件的每个chunk,然后循环调用每个handlers处理当前chunk。每个handlers最后返回一个Filelike object,因此理论上上传一个文件,server端会产生len(handlers)个文件对象,但是我们通过FILES[FILENAME]只会返回一个object,这是因为FILES是 django.utils.datastructures.MultiValueDict 类型,接口类似dict,但是逻辑不同,参考代码:link。 GET & POST 类型为 class QueryDict(MultiValueDict),集成增加了 mutable 开关。
classBaseHandler: """Manage the invocation of a WSGI application""" ... defrun(self, application): """Invoke the application""" # Note to self: don't move the close()! Asynchronous servers shouldn't # call close() from finish_response(), so if you close() anywhere but # the double-error branch here, you'll break asynchronous servers by # prematurely closing. Async servers must return from 'run()' without # closing if there might still be output to iterate over. try: self.setup_environ() self.result = application(self.environ, self.start_response) self.finish_response() except: try: self.handle_error() except: # If we get an error handling an error, just give up already! self.close() raise# ...and let the actual server figure it out. deffinish_response(self): """Send any iterable data, then close self and the iterable Subclasses intended for use in asynchronous servers will want to redefine this method, such that it sets up callbacks in the event loop to iterate over the data, and to call 'self.close()' once the response is finished. """ try: ifnot self.result_is_file() ornot self.sendfile(): for data in self.result: self.write(data) self.finish_content() finally: self.close()