using File storage

647 views
Skip to first unread message

Jiri Barton

unread,
Aug 28, 2008, 11:44:57 AM8/28/08
to Django users
What is the preferred way of storing generated content into file
models?

class Chart(models.Model):
xml = models.FileField(upload_to='charts')
...

I would like compute the image on the fly, using some data in the
database. How should I store the generated data? How should I use File
storage for this task?

I would like Django to take care of the file naming for me. I would
like to use a one-liner such as

Chart.objects.create(xml=default_storage.save('data.xml', data))

where data is a string, but that gives me

AttributeError: 'str' object has no attribute 'chunks'

The example from http://www.djangoproject.com/documentation/files/#storage-objects
does not work for me either:

>>> from django.core.files.storage import default_storage

>>> path = default_storage.save('/path/to/file', 'new content')

This will give me

<type 'exceptions.AttributeError'>: 'str' object has no attribute
'chunks'

Should I use the class File directly? How? For File.save() to work, I
would need an associated an object. Please advise.

Thank you

Tim Kersten

unread,
Aug 28, 2008, 12:03:35 PM8/28/08
to django...@googlegroups.com
iirc, you can use http://docs.python.org/lib/module-StringIO.html to
have a file like object from a string, and use that to make your
django File object (
http://www.djangoproject.com/documentation/files/#the-file-object ).

There's probably a better way than this though so you might want to
wait for other replies.

import StringIO
from django.core.files import File
f = StringIO.StringIO()
f.write(data)
myfile = File(f)
Chart.objects.create(xml=default_storage.save('data.xml', myfile))

Tim ^,^

Marty Alchin

unread,
Aug 28, 2008, 12:09:36 PM8/28/08
to django...@googlegroups.com
On Thu, Aug 28, 2008 at 11:44 AM, Jiri Barton <whis...@gmail.com> wrote:
> I would like Django to take care of the file naming for me. I would
> like to use a one-liner such as
>
> Chart.objects.create(xml=default_storage.save('data.xml', data))

You're nearly there for getting this to work, it's just the matter of
how you're passing in the data. Try importing ContentFile from
django.core.files.base, and using it like so:

Chart.objects.create(xml=default_storage.save('data.xml', ContentFile(data)))

> The example from http://www.djangoproject.com/documentation/files/#storage-objects
> does not work for me either:
>
>>>> from django.core.files.storage import default_storage
>
>>>> path = default_storage.save('/path/to/file', 'new content')
>
> This will give me
>
> <type 'exceptions.AttributeError'>: 'str' object has no attribute
> 'chunks'

Egad! Would you mind opening a ticket for this? That example is
definitely wrong, and will need to be updated.

-Gul

Tim Kersten

unread,
Aug 28, 2008, 12:18:27 PM8/28/08
to django...@googlegroups.com
> Chart.objects.create(xml=default_storage.save('data.xml', ContentFile(data)))

ha, I was almost certain that django wouldn't make it as hard as I had
explained it. :-D Glad to see it's this easy!

Tim ^,^

julianb

unread,
Aug 28, 2008, 2:18:12 PM8/28/08
to Django users
On Aug 28, 6:03 pm, "Tim Kersten" <t...@io41.com> wrote:
> There's probably a better way than this though so you might want to
> wait for other replies.
>
> import StringIO
> from django.core.files import File
> f = StringIO.StringIO()
> f.write(data)
> myfile = File(f)
> Chart.objects.create(xml=default_storage.save('data.xml', myfile))

That's not working for me, I get AttributeError: StringIO instance has
no attribute 'name'...

Tim Kersten

unread,
Aug 28, 2008, 2:44:22 PM8/28/08
to django...@googlegroups.com
Oh, I should have seen that coming. (That's the bad thing when you
write code without testing it yourself... something is often missed
:-)

This should fix the error you got:

import StringIO
from django.core.files import File
f = StringIO.StringIO()

f.name, f.mode = 'data.xml', 'r'
f.write(data)
myfile = File(f)
Chart.objects.create(xml=default_storage.save(f.name, myfile))


However, Marty's solution seems a lot nicer. Did that not work? I've
never done anything like what I've shown you - it was more or less a
straight guess as to how it might work. Marty's solution looks a lot
more correct and a lot cleaner too. Perhaps you should be trying to
make that work instead?


Tim ^,^

julianb

unread,
Aug 28, 2008, 2:53:14 PM8/28/08
to Django users
On Aug 28, 8:44 pm, "Tim Kersten" <t...@io41.com> wrote:
> This should fix the error you got:
>
> import StringIO
> from django.core.files import File
> f = StringIO.StringIO()
> f.name, f.mode = 'data.xml', 'r'
> f.write(data)
> myfile = File(f)
> Chart.objects.create(xml=default_storage.save(f.name, myfile))
>
> However, Marty's solution seems a lot nicer. Did that not work? I've
> never done anything like what I've shown you - it was more or less a
> straight guess as to how it might work. Marty's solution looks a lot
> more correct and a lot cleaner too. Perhaps you should be trying to
> make that work instead?

AttributeError: StringIO instance has no attribute 'name'

I tried several things, I think Marty's solution was among them. It
did not throw errors, but the file I got was 0 bytes. I will try again
and check if I made a mistake or so...

julianb

unread,
Aug 28, 2008, 3:13:09 PM8/28/08
to Django users
On Aug 28, 8:53 pm, julianb <julian....@gmail.com> wrote:
> I tried several things, I think Marty's solution was among them. It
> did not throw errors, but the file I got was 0 bytes. I will try again
> and check if I made a mistake or so...

Okay, I solved the puzzle. The following works:

big = StringIO.StringIO() # you have a StringIO
...
image.save(big, "JPEG", quality=70) # write something to the StringIO
...
# Photo is a model that has an image field
photo = Photo(user=creator)
# use getvalue because ContentFile just needs content
big_file = ContentFile(big.getvalue())
# use save method of image field, no other function!
photo.data.save("%s.jpg" % name, big_file)
Reply all
Reply to author
Forward
0 new messages