script adding FileField, no attribute chunks

671 views
Skip to first unread message

Mitch Anderson

unread,
Nov 15, 2010, 7:24:10 PM11/15/10
to django...@googlegroups.com, mi...@metauser.net
I'm having a problem with a command script that I want to create a
object that has a FileField as part of the model.

My Model Looks like this:

class Files(models.Model):
STATUS = (
('unknown', 'Unknown'),
('down', 'Downloading'),
('done', 'Done'),
('dup', 'Duplicate')
)
file = models.FileField(upload_to = "files/%Y-%m")
date_added = models.DateTimeField(auto_now_add=True)
date_started = models.DateTimeField(blank=True)
date_finished = models.DateTimeField(blank=True)
date_pub = models.DateTimeField(blank=True)
status = models.CharField(max_length=8, choices=STATUS)
download = models.BooleanField(blank=True)


And then in my command script, it looks like this:

class Command(BaseCommand):
help = 'Scan RSS Feed and Download Files.'

def getFiles(self):
for tors in self.fetch:
newfile = Files()
filename = files['link'].rsplit('/',1)[1]
u = urllib2.urlopen(files['link'])
localFile = open('/tmp/%s' % filename, 'w')
localFile.write(u.read())
localFile.close()
#newfile.file.open('/tmp/%s' % filename, 'b')
newfile.file.save(filename,open('/tmp/%s' % filename).read())
#newfile.file('/tmp/%s' % filename)
newfile.date_pub(files['pubdate'])
newfile.status('unknown')
newfile.download('True')
newfile.save()

def getLink(self,mfile):
m = re.compile(mfile.regex,re.I)
feed = self.feed

for e in feed.entries:
if m.search(e.link):
self.fetch.append({'name': mfile.name, 'link': e.link, 'pubdate':
e.updated_parsed })


def handle(self, *args, **options):
mf = MyFiles.objects.all()
# fetch and parse RSS Feed
self.feed = feedparser.parse(Feeds.objects.all()[0].rss)
self.fetch = []
# Set self.fetch list
for s in mf:
self.getLink(s)

# download, record and save files
self.getFiles()


But I get the following error when I run it:

File "/home/mitch/Projects/meta/Filez/management/commands/files_check.py",
line 30, in getFiles
newfile.file.save(filename,open('/tmp/%s' % filename).read())
File "/usr/lib/pymodules/python2.6/django/db/models/fields/files.py",
line 92, in save
self.name = self.storage.save(name, content)
File "/usr/lib/pymodules/python2.6/django/core/files/storage.py",
line 48, in save
name = self._save(name, content)
File "/usr/lib/pymodules/python2.6/django/core/files/storage.py",
line 168, in _save
for chunk in content.chunks():
AttributeError: 'str' object has no attribute 'chunks'

Which, from what I've seen... chunks is part of an HTTP POST file
object? So... its not supposed to work as command line script? or
what am I doing wrong?

Tom Evans

unread,
Nov 16, 2010, 5:28:47 AM11/16/10
to django...@googlegroups.com, mi...@metauser.net
> --
> You received this message because you are subscribed to the Google Groups "Django users" group.
> To post to this group, send email to django...@googlegroups.com.
> To unsubscribe from this group, send email to django-users...@googlegroups.com.
> For more options, visit this group at http://groups.google.com/group/django-users?hl=en.
>
>

Django doesn't want a python file or text for a django file field, it
wants a django.core.files.File. I find the easiest one to use is the
InMemoryUploadedFile. Here is a snippet I use for fetching an image
from the web, and creating a django.core.files.File object that can be
assigned to a FileField or ImageField on a model:

h = httplib2.Http()
req, content = h.request(uri)
if req['status'] != '200':
print u'Failed to fetch image from %s' % uri
return None

import cStringIO
from django.core.files.uploadedfile import InMemoryUploadedFile
out = cStringIO.StringIO()
out.write(content)
return InMemoryUploadedFile(
file=out,
field_name=field,
name=name,
content_type=req['content-type'],
size=out.tell(),
charset=None)

field should be the name of the field on the model, name should be the
file name of the resource.

There may be neater ways of doing this, but this keeps it in memory
until django saves it to the upload_to location specified on the
model, and avoids writing it to disk only for django to write it to
disk again.

Cheers

Tom

Mitch Anderson

unread,
Nov 16, 2010, 4:36:57 PM11/16/10
to Tom Evans, django...@googlegroups.com
Awesome that worked perfectly!  Thanks Tom!

Andrew Marder

unread,
Dec 1, 2010, 7:23:06 AM12/1/10
to Django users
I'm trying to add a bunch of files from disk into my django database.
Here's the helper function I've written so far:

def django_file(path, field_name, content_type):
# adapted from here: http://groups.google.com/group/django-users/browse_thread/thread/834f988876ff3c45/
from django.core.files.uploadedfile import InMemoryUploadedFile
f = open(path)
return InMemoryUploadedFile(
file=f,
field_name=field_name,
name=file.name,
content_type=content_type,
size=os.path.getsize(path),
charset=None)

I'm calling it like so:
django_file("path-to-jpg-file", field_name="image",
content_type="image/jpeg")

Here's the error I'm getting:
Traceback (most recent call last):
File "<console>", line 1, in <module>
File "/home/amarder/Documents/nmis/odk_dropbox/views.py", line 49,
in import_instances_folder
f = django_file(xml_files[0], field_name="xml_file",
content_type="text/xml")
File "/home/amarder/Documents/nmis/odk_dropbox/views.py", line 70,
in django_file
charset=None)
File "/home/amarder/Documents/environments/nmis/lib/python2.6/site-
packages/django/core/files/uploadedfile.py", line 90, in __init__
super(InMemoryUploadedFile, self).__init__(file, name,
content_type, size, charset)
File "/home/amarder/Documents/environments/nmis/lib/python2.6/site-
packages/django/core/files/uploadedfile.py", line 30, in __init__
super(UploadedFile, self).__init__(file, name)
File "/home/amarder/Documents/environments/nmis/lib/python2.6/site-
packages/django/core/files/base.py", line 17, in __init__
self.name = name
File "/home/amarder/Documents/environments/nmis/lib/python2.6/site-
packages/django/core/files/uploadedfile.py", line 46, in _set_name
name = os.path.basename(name)
File "/home/amarder/Documents/environments/nmis/lib/python2.6/
posixpath.py", line 111, in basename
i = p.rfind('/') + 1
AttributeError: 'member_descriptor' object has no attribute 'rfind'

Any suggestions?

Andrew

On Nov 16, 4:36 pm, Mitch Anderson <mi...@metauser.net> wrote:

Tom Evans

unread,
Dec 1, 2010, 7:32:53 AM12/1/10
to django...@googlegroups.com
On Wed, Dec 1, 2010 at 12:23 PM, Andrew Marder
<andrew....@gmail.com> wrote:
> I'm trying to add a bunch of files from disk into my django database.
> Here's the helper function I've written so far:
>
> def django_file(path, field_name, content_type):
>    # adapted from here: http://groups.google.com/group/django-users/browse_thread/thread/834f988876ff3c45/
>    from django.core.files.uploadedfile import InMemoryUploadedFile
>    f = open(path)
>    return InMemoryUploadedFile(
>        file=f,
>        field_name=field_name,
>        name=file.name,

This should be 'f.name', not 'file.name'. file is a built in class in
python, and file.name is a member of that class, not your file name.

Cheers

Tom

>        content_type=content_type,
>        size=os.path.getsize(path),
>        charset=None)
>

Andrew Marder

unread,
Dec 1, 2010, 7:50:19 AM12/1/10
to django...@googlegroups.com
Awesome! Thanks so much for the help.

Andrew

urukay

unread,
Dec 15, 2010, 3:27:53 AM12/15/10
to Django users
Hi,

can any one help on this problem?

pic_file = os.path.join(settings.MEDIA_ROOT, 'signature
\invalid.png')
f = open(pic_file, 'r')
picture = InMemoryUploadedFile(
file=f,
field_name='image',
name='invalid_new.png',
content_type='image/png',
size=os.path.getsize(pic_file),
charset=None,
)
pic = DigitalSignaturePicture(kind=1, image=picture)
pic.save()

And i get this error:

Traceback (most recent call last):
File "D:\Workspace\yau\py\manage.py", line 11, in <module>
execute_manager(settings)
File "C:\Python25\lib\site-packages\django\core\management
\__init__.py", line 438, in execute_manager
utility.execute()
File "C:\Python25\lib\site-packages\django\core\management
\__init__.py", line 379, in execute
self.fetch_command(subcommand).run_from_argv(self.argv)
File "C:\Python25\lib\site-packages\django\core\management\base.py",
line 191, in run_from_argv
self.execute(*args, **options.__dict__)
File "C:\Python25\lib\site-packages\django\core\management\base.py",
line 218, in execute
output = self.handle(*args, **options)
File "C:\Python25\lib\site-packages\django\core\management\base.py",
line 347, in handle
return self.handle_noargs(**options)
File "D:\Workspace\yau\py\help\management\commands\helpupdate.py",
line 6, in handle_noargs
update_faq(silent=False)
File "D:\Workspace\yau\py\help\updater.py", line 321, in update
DigitalSignatureHelpUpdater(silent).update()
File "D:\Workspace\yau\py\help\updater.py", line 281, in update
pic.save()
File "D:\Workspace\yau\ext\imagekit\models.py", line 145, in save
self._pre_cache()
File "D:\Workspace\yau\ext\imagekit\models.py", line 110, in
_pre_cache
prop._create()
File "D:\Workspace\yau\ext\imagekit\specs.py", line 63, in _create
self._img, self._fmt = self.spec.process(Image.open(fp),
self._obj)
File "C:\Python25\Lib\site-packages\PIL\Image.py", line 1980, in
open
raise IOError("cannot identify image file")
IOError: cannot identify image file

Thanks a lot

Radovan

On 1. Dec., 13:32 h., Tom Evans <tevans...@googlemail.com> wrote:
> On Wed, Dec 1, 2010 at 12:23 PM, Andrew Marder
>
> <andrew.n.mar...@gmail.com> wrote:
> > I'm trying to add a bunch of files from disk into my django database.
> > Here's the helper function I've written so far:
>
> > def django_file(path, field_name, content_type):
> >    # adapted from here:http://groups.google.com/group/django-users/browse_thread/thread/834f...
Reply all
Reply to author
Forward
0 new messages