On Tue, Nov 16, 2010 at 12:24 AM, Mitch Anderson <xofre...@gmail.com> wrote:
> 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?
>
> --
> You received this message because you are subscribed to the Google Groups 
> "Django users" group.
> To post to this group, send email to django-us...@googlegroups.com.
> To unsubscribe from this group, send email to 
> django-users+unsubscr...@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

-- 
You received this message because you are subscribed to the Google Groups 
"Django users" group.
To post to this group, send email to django-us...@googlegroups.com.
To unsubscribe from this group, send email to 
django-users+unsubscr...@googlegroups.com.
For more options, visit this group at 
http://groups.google.com/group/django-users?hl=en.

Reply via email to