Django 1.3 स्वीकार्य है। तो मैं या तो request.raw_post_data या request.read() (या वैकल्पिक रूप से कुछ एक्सेस की अन्य बेहतर विधि) के साथ कुछ कर सकता हूं। कोई भी विचार?
आप request.raw_post_data
को छू जाना नहीं करना चाहते - कि स्मृति में पूरे अनुरोध शरीर पढ़ने, जो आप फ़ाइल अपलोड के बारे में बात कर रहे हैं एक बहुत बड़ी राशि हो सकता है का तात्पर्य है, तो request.read()
जाने का रास्ता है। आप Django < = 1.2 के साथ भी ऐसा कर सकते हैं, लेकिन इसका मतलब निजी इंटरफेस का उपयोग करने का सही तरीका जानने के लिए HttpRequest
में खोदना है, और यह सुनिश्चित करने के लिए एक असली ड्रैग है कि आपका कोड Django> = 1.3।
मेरा सुझाव था कि आप क्या करना चाहते हैं को दोहराने के लिए existing file upload behaviour parts of the MultiPartParser
class है:
request.upload_handlers
(जो डिफ़ॉल्ट रूप से किया जाएगा MemoryFileUploadHandler
& TemporaryFileUploadHandler
)
- अनुरोध की सामग्री लंबाई निर्धारित से अपलोड हाथ के बल्लेबाजों को पुनः प्राप्त (
HttpRequest
या MultiPartParser
में सामग्री-लंबाई की खोज करने के लिए सही तरीका देखने के लिए।)
- अपलोड की गई फ़ाइल के फ़ाइल नाम का निर्धारण करें, या तो क्लाइंट को यूआरएल के अंतिम पथ भाग का उपयोग करके निर्दिष्ट करें या क्लाइंट को इसे the
Content-Disposition
header के "filename =" भाग में निर्दिष्ट करने दें।
- प्रत्येक हैंडलर के लिए, फोन प्रासंगिक आर्ग (एक फ़ील्ड नाम ऊपर मजाक)
request.read()
का उपयोग कर और प्रत्येक टुकड़ा के लिए handler.receive_data_chunk()
बुला मात्रा में अनुरोध शरीर पढ़ें साथ handler.new_file
।
- प्रत्येक हैंडलर कॉल
handler.file_complete()
पर कॉल करें, और यदि यह मान देता है, तो वह अपलोड की गई फ़ाइल है।
मैं क्या भेजा जा रहा है की माइम प्रकार कैसे मान सकते हैं? अगर मुझे यह सही मिला है, तो पुट बॉडी केवल प्रस्ताव के बिना फ़ाइल है। इसलिए मुझे उपयोगकर्ता को उनके शीर्षलेखों में माइम प्रकार निर्दिष्ट करने की आवश्यकता है?
या तो क्लाइंट को इसे सामग्री-प्रकार शीर्षलेख में निर्दिष्ट करने दें, या मीडिया प्रकार का अनुमान लगाने के लिए python's mimetype module का उपयोग करें।
मुझे यह जानने में दिलचस्पी होगी कि आप इस पर कैसे पहुंचते हैं - यह कुछ है जो मैं खुद को देखने का मतलब रहा हूं, अगर आप मुझे यह बताने के लिए टिप्पणी कर सकते हैं कि यह कैसे हो सकता है तो बढ़िया हो!
संपादित Ninefingers के रूप में अनुरोध द्वारा, यह मैं क्या किया और इसके बाद के संस्करण और Django स्रोत पर पूरी तरह से आधारित है।
upload_handlers = request.upload_handlers
content_type = str(request.META.get('CONTENT_TYPE', ""))
content_length = int(request.META.get('CONTENT_LENGTH', 0))
if content_type == "":
return HttpResponse(status=400)
if content_length == 0:
# both returned 0
return HttpResponse(status=400)
content_type = content_type.split(";")[0].strip()
try:
charset = content_type.split(";")[1].strip()
except IndexError:
charset = ""
# we can get the file name via the path, we don't actually
file_name = path.split("/")[-1:][0]
field_name = file_name
चूंकि मैं यहां एपीआई परिभाषित कर रहा हूं, क्रॉस ब्राउज़र समर्थन चिंता का विषय नहीं है। जहां तक मेरा प्रोटोकॉल चिंतित है, सही जानकारी की आपूर्ति नहीं करना एक टूटा अनुरोध है। मैं दो दिमाग में हूं कि क्या मैं image/jpeg; charset=binary
कहूंगा या यदि मैं अस्तित्वहीन वर्णों को अनुमति देने जा रहा हूं। किसी भी मामले में, मैं क्लाइंट-साइड ज़िम्मेदारी के रूप में वैध रूप से Content-Type
सेटिंग डाल रहा हूं।
इसी प्रकार, मेरे प्रोटोकॉल के लिए, फ़ाइल का नाम पास हो गया है। मुझे यकीन नहीं है कि field_name
पैरामीटर के लिए क्या है और स्रोत ने कई संकेत नहीं दिए हैं।
नीचे क्या होता है वास्तव में यह दिखने से कहीं अधिक सरल है। यदि आप कच्चे इनपुट को संभालेंगे तो आप प्रत्येक हैंडलर से पूछेंगे। उपर्युक्त राज्यों के लेखक के रूप में, आपको डिफ़ॉल्ट रूप से MemoryFileUploadHandler
& TemporaryFileUploadHandler
मिल गया है। ठीक है, यह MemoryFileUploadHandler
दिखाता है जब new_file
बनाने के लिए कहा जाएगा कि यह फ़ाइल को संभालेगा या नहीं (विभिन्न सेटिंग्स के आधार पर)। यदि यह तय करता है कि यह जा रहा है, तो यह एक अपवाद फेंकता है, अन्यथा यह फ़ाइल नहीं बनाएगा और एक और हैंडलर को ले जाने देता है।
मुझे यकीन नहीं है कि counters
का उद्देश्य क्या था, लेकिन मैंने इसे स्रोत से रखा है। बाकी सीधा होना चाहिए।
if request.content_type.startswith('multipart'):
put, files = request.parse_file_upload(request.META, request)
request.FILES.update(files)
request.PUT = put.dict()
else:
request.PUT = QueryDict(request.body).dict()
में की तरह फाइलों और अन्य डेटा का उपयोग करने में सक्षम होने की: मैं इस तरह दिया समाधान संशोधित
counters = [0]*len(upload_handlers)
for handler in upload_handlers:
result = handler.handle_raw_input("",request.META,content_length,"","")
for handler in upload_handlers:
try:
handler.new_file(field_name, file_name,
content_type, content_length, charset)
except StopFutureHandlers:
break
for i, handler in enumerate(upload_handlers):
while True:
chunk = request.read(handler.chunk_size)
if chunk:
handler.receive_data_chunk(chunk, counters[i])
counters[i] += len(chunk)
else:
# no chunk
break
for i, handler in enumerate(upload_handlers):
file_obj = handler.file_complete(counters[i])
if not file_obj:
# some indication this didn't work?
return HttpResponse(status=500)
else:
# handle file obj!
+1 धन्यवाद, ऐसा लगता है कि ऐसा हो सकता है। जब मैं काम पर वापस आऊंगा तो मैं इसे एक बार दूंगा और मैं परिणामों के साथ रिपोर्ट करूंगा। –
यह एक आकर्षण की तरह काम करता है, मैं इसे दिन के अंत में अपने उत्तर में संपादित कर दूंगा। अनुरोध के अनुसार –
, मैंने अपना कोड आपके उत्तर में संपादित कर दिया है। यदि आपके पास कोई सुधार है, तो उन्हें संपादित करने में संकोच न करें। मैं अपने स्वयं के प्रश्न का उत्तर आपके द्वारा प्राप्त किए गए काम से नहीं करना चाहता था, इसलिए एक पोस्ट के बजाय संपादन। –