2012-10-14 9 views
15

संभव डुप्लिकेट:
Serving dynamically generated ZIP archives in DjangoDjango - एकाधिक फ़ाइलों की एक पिन बना सकते हैं और इसे डाउनलोड करने योग्य

(किसी भी संभावित डुप्लीकेट करने के लिए मुझसे बात करने के लिए स्वतंत्र महसूस अगर मैं उन्हें याद किया है)

मैंने इस स्निपेट को देखा है: http://djangosnippets.org/snippets/365/

और इस answer:

लेकिन मुझे आश्चर्य है कि कैसे मैं उन्हें अपने जरूरत के अनुरूप करने के tweak कर सकते हैं: मैं चाहता हूँ कई फ़ाइलें ज़िप की जा करने के लिए और संग्रह एक लिंक के माध्यम से डाउनलोड के रूप में उपलब्ध है (या गतिशील रूप से एक दृश्य के माध्यम से उत्पन्न किया था)। मैं पाइथन और डीजेगो के लिए नया हूं इसलिए मुझे नहीं पता कि इसके बारे में कैसे जाना है।

अग्रिम धन्यवाद!

+0

फ़ाइलवापर के स्रोत को देखते हुए, ऐसा लगता है कि यह केवल एक फ़ाइल स्वीकार करता है। मुझे नहीं पता कि फाइलों के माध्यम से लूपिंग send_zipfile स्निपेट – yretuta

+0

फ़ाइलों के माध्यम से लूपिंग और उन्हें संग्रह में लिखने का तरीका है मेरे सिद्धांत में काम करेगा। –

उत्तर

40

मैं duplicate question जो विली से जुड़ा हुआ पर इस पोस्ट किया है, लेकिन जब से एक इनाम के साथ सवालों के डुप्लिकेट के रूप में बंद नहीं किया जा सकता है, साथ ही यह भी यहाँ नकल हो सकता है:

import os 
import zipfile 
import StringIO 

from django.http import HttpResponse 


def getfiles(request): 
    # Files (local path) to put in the .zip 
    # FIXME: Change this (get paths from DB etc) 
    filenames = ["/tmp/file1.txt", "/tmp/file2.txt"] 

    # Folder name in ZIP archive which contains the above files 
    # E.g [thearchive.zip]/somefiles/file2.txt 
    # FIXME: Set this to something better 
    zip_subdir = "somefiles" 
    zip_filename = "%s.zip" % zip_subdir 

    # Open StringIO to grab in-memory ZIP contents 
    s = StringIO.StringIO() 

    # The zip compressor 
    zf = zipfile.ZipFile(s, "w") 

    for fpath in filenames: 
     # Calculate path for file in zip 
     fdir, fname = os.path.split(fpath) 
     zip_path = os.path.join(zip_subdir, fname) 

     # Add file, at correct path 
     zf.write(fpath, zip_path) 

    # Must close zip for all contents to be written 
    zf.close() 

    # Grab ZIP file from in-memory, make response with correct MIME-type 
    resp = HttpResponse(s.getvalue(), mimetype = "application/x-zip-compressed") 
    # ..and correct content-disposition 
    resp['Content-Disposition'] = 'attachment; filename=%s' % zip_filename 

    return resp 
+1

'सामग्री-विस्थापन: अनुलग्नक वापस लौटना अच्छा होगा; filename = "..." 'हेडर ([यहां चश्मा] (http://www.w3.org/Protocols/rfc2616/rfc2616-sec19.html#sec19.5.1)) फ्रंटेंड सर्वर गलत कॉन्फ़िगरेशन की संभावना को कम करने के लिए हस्तक्षेप करना आपकी प्रतिक्रिया और ब्राउज़र में यह सब spewing। –

+0

@ मिखाइलसायपिन आह, दिलचस्प - जोड़ा गया! – dbr

+7

ध्यान दें कि 'mimetype' पैरामीटर को बहिष्कृत कर दिया गया है, इसे Django 1.5+ –

3

तो जैसा कि मैं समझता हूँ कि अपने समस्या नहीं है गतिशील रूप से इस फाइल उत्पन्न कैसे है, लेकिन लोग इसे डाउनलोड करने के लिए एक लिंक बनाने ...

क्या मेरा सुझाव है निम्नलिखित है:

0) अपनी फ़ाइल के लिए एक मॉडल बनाने के लिए, यदि आप चाहते हैं इसे गतिशील रूप से फ़ाइलफ़ी का उपयोग न करें बड़ा, लेकिन केवल इस फ़ाइल को उत्पन्न करने के लिए आपको जो जानकारी चाहिए:

class ZipStored(models.Model): 
    zip = FileField(upload_to="/choose/a/path/") 

1) अपना ज़िप बनाएं और स्टोर करें। यह कदम महत्वपूर्ण है, आप स्मृति में अपने ज़िप बनाते हैं और फिर FileField निर्दिष्ट करने के लिए यह डाली:

function create_my_zip(request, [...]): 
    [...] 
    # This is a in-memory file 
    file_like = StringIO.StringIO() 
    # Create your zip, do all your stuff 
    zf = zipfile.ZipFile(file_like, mode='w') 
    [...] 
    # Your zip is saved in this "file" 
    zf.close() 
    file_like.seek(0) 
    # To store it we can use a InMemoryUploadedFile 
    inMemory = InMemoryUploadedFile(file_like, None, "my_zip_%s" % filename, 'text/plain', file_like.len, None) 
    zip = ZipStored(zip=inMemory) 
    # Your zip will be stored! 
    zip.save() 
    # Notify the user the zip was created or whatever 
    [...] 

2) एक ऐसा url बनाएं, उदाहरण के लिए एक नंबर आईडी मिलान मिलता है, आप भी एक का उपयोग कर सकते slugfield (this)

url(r'^get_my_zip/(\d+)$', "zippyApp.views.get_zip") 

3) अब देखने के लिए, इस दृश्य आईडी यूआरएल में पारित मिलान फ़ाइल वापस आ जाएगी, तो आप भी आईडी के बजाय पाठ संदेश भेजने, स्लग उपयोग कर सकते हैं, और फ़िल्टरिंग प्राप्त करना अपने स्लगफील्ड द्वारा।

function get_zip(request, id): 
    myzip = ZipStored.object.get(pk = id) 
    filename = myzip.zip.name.split('/')[-1] 
    # You got the zip! Now, return it! 
    response = HttpResponse(myzip.file, content_type='text/plain') 
    response['Content-Disposition'] = 'attachment; filename=%s' % filename 
+1

में लिखें 'ZipStored._meta.get_field_by_name (' ज़िप ') का उपयोग क्यों नहीं करें। file_to सीधे फाइल सिस्टम पर फ़ाइल बनाने के लिए। अपने वेबसर्वर को एक टन रैम और संभावित डॉस वैक्टर सहेजें? – Thomas

+0

मुझे फ़ाइलफ़ाइल से फ़ाइल नाम कैसे प्राप्त करना चाहिए और इसे अपने कोड में "फ़ाइल नाम" var के साथ उपयोग करना चाहिए? – yretuta

संबंधित मुद्दे