2010-07-25 15 views
6
class MyModel(models.Model) 
image = models.FileField(upload_to="blagh blagh...") 
#more spam... 

फैली मैं स्मृति में एक फ़ाइल है और मैं, विधि बचाने Django FileField के माध्यम से इसे सहेजना चाहते इस तरह:वर्ग की तरह एक StringIO, कि django.core.files.File

photo.image.save(name, buffer) # second arg should be django File 

मैं मैंने स्ट्रिंगियो का उपयोग करने की कोशिश की है, लेकिन यह django.core.files.File का विस्तार नहीं करता है और इस प्रकार विधि भाग() को लागू नहीं करता है। मैं इसे इस तरह एक फ़ाइल वस्तु में लिपटे है:

buffile = File(buffer, name) # first argument should be a file 
photo.image.save(name, buffile) 

लेकिन फ़ाइल तरीकों की आपूर्ति की फ़ाइल के आकार और नाम फ़ील्ड का उपयोग करें। स्ट्रिंगियो उन्हें परिभाषित नहीं करता है। मुझे this मिला है, लेकिन लिंक मर चुका है

उत्तर

7

आप बाइट्स, जिसे आप एक FileField/ImageField को बचाना चाहते हैं तो की एक धारा मिल गया है, तो यहां कुछ कोड है कि मदद दे सकता है:

>>> from django.core.files.uploadedfile import InMemoryUploadedFile 
>>> from cStringIO import StringIO 
>>> buf = StringIO(data) # `data` is your stream of bytes 
>>> buf.seek(0, 2) # Seek to the end of the stream, so we can get its length with `buf.tell()` 
>>> file = InMemoryUploadedFile(buf, "image", "some_filename.png", None, buf.tell(), None) 
>>> photo.image.save(file.name, file) # `photo` is an instance of `MyModel` 
>>> photo.image 
<ImageFieldFile: ...> 

कुछ नोट:

  • आप छवि के लिए जो भी नाम चाहते हैं उसे बना सकते हैं, लेकिन आप शायद विस्तार को सटीक रखना चाहते हैं
  • InMemoryUploadedFile पर दूसरा तर्क आपके मॉडल में फ़ील्ड का नाम है, इसलिए "छवि"

यह थोड़ा छोटा है, लेकिन यह काम पूरा हो जाता है। उम्मीद है कि एपीआई 1.3/4 में थोड़ी अधिक साफ हो जाएगी।

संपादित करें:
ऐसा करने का एक बहुत ही सरल तरीका के लिए Jason's answer देखें, लेकिन तब भी आप छवि का फ़ाइल नाम पता करने के लिए चाहता हूँ।

+0

धन्यवाद आदमी :) – exshinigami

0

Image कक्षा का उपयोग करें।

+0

मुझे लगता है कि माना जाता है, लेकिन फिर मैं फ़ाइलों को नाम के लिए Django तंत्र का उपयोग नहीं होगा (यदि किसी विशेष के साथ एक फ़ाइल नाम मौजूद है, फ़ाइल नाम में अंडरस्कोर जोड़ें)। और हाँ, मुझे पता है, मैं इसे अपने आप कर सकता था और मैं इसे अन्य तरीके से कर सकता था, लेकिन अगर मैंने ऐसा किया, तो यह सबसे अच्छा होगा, जैसा कि मैंने पहले बताया था। – joozek

26

आप फ़ाइल

from django.core.files.base import ContentFile 

photo.image.save(name, ContentFile(buffer)) 
+3

साफ! यह मेरे समाधान से इतना आसान है ... + 1 – elo80ka

7

पुन जेसन के जवाब के बजाय ContentFile उपयोग कर सकते हैं। ध्यान दें कि ContentFile केवल स्ट्रिंग स्वीकार करता है, न कि किसी भी फ़ाइल जैसी वस्तु।

from django.core.files.base import * 

class StreamFile(ContentFile): 
    """ 
    Django doesn't provide a File wrapper suitable 
    for file-like objects (eg StringIO) 
    """ 
    def __init__(self, stream): 
     super(ContentFile, self).__init__(stream) 
     stream.seek(0, 2) 
     self.size = stream.tell() 

अब तुम इस तरह सामान कर सकते हैं - - यहाँ एक है कि करता है

photo.image.save(name, StreamFile(io)) 
+0

यह वास्तविक सही उत्तर है, मेरे दिन को बचाया! – danigosa

+0

एफडब्ल्यूआईडब्ल्यू, आजकल 'कंटेंटफाइल' बाइट स्वीकार करता है। –

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