如何在django中的FileField中保存本地文件

时间:2013-04-16 22:37:55

标签: python django filefield

我需要通过SOAP Web服务获取文件,并使用django的FileField将其保存到模型中。

我做了以下事情:

在我的SOAP Wrapper中,我将文件保存在临时目录

# ... get the file and file_name and decode put it into a variable called data
f = open('tmp/%s' % filename, 'w+')
f.write(data)
# build a dictionary with another useful metadata

这里没什么奇怪的(我猜)

然后,在我看来,我做了以下几点:

from django.core.files import File
for ext in extensions:
    messages = helpers.get_new_messages(ext)
    for msg in messages:
        vm = VoiceMessage()
        filename = '%s-%s' % (ext.t_account_name, msg['name'])
        vm.extension = ext 
        vm.origin = msg['origin']
        vm.date = msg['when']
        vm.message.save(filename, File(msg['file'])) # Error is raised here
        msg['file'].close()
        vm.save()

我收到以下错误:

/ account / dashboard / messages /上的TypeError 预期的字符串或缓冲区

我已经尝试过了 How to assign a local file to the FileField in Django?

这个 Django - how to create a file and save it to a model's FileField?

我错过了什么吗?

编辑2013年4月17日:添加追溯

我调试了它并返回了类型(msg [' file'])调用:

<type 'file'>

更具体地说:

<open file './voice_message_2013-4-15_22-41-58.au', mode 'w+' at 0xca0fe40>

这是完整的追溯。

Internal Server Error: /account/dashboard/messages/
Traceback (most recent call last):
  File "/home/israelord/.virtualenvs/ringtu-env/local/lib/python2.7/site-packages/django/core/handlers/base.py", line 115, in get_response
    response = callback(request, *callback_args, **callback_kwargs)
  File "/home/israelord/.virtualenvs/ringtu-env/local/lib/python2.7/site-packages/django/contrib/auth/decorators.py", line 25, in _wrapped_view
    return view_func(request, *args, **kwargs)
  File "/home/israelord/Work/4geeks/ringtu/ringtu/profiles/views.py", line 239, in account_dashboard_messages
    vm.message.save(filename, File(msg['file']))
  File "/home/israelord/.virtualenvs/ringtu-env/local/lib/python2.7/site-packages/django/db/models/fields/files.py", line 95, in save
    self.instance.save()
  File "/home/israelord/.virtualenvs/ringtu-env/local/lib/python2.7/site-packages/django/db/models/base.py", line 546, in save
    force_update=force_update, update_fields=update_fields)
  File "/home/israelord/.virtualenvs/ringtu-env/local/lib/python2.7/site-packages/django/db/models/base.py", line 650, in save_base
    result = manager._insert([self], fields=fields, return_id=update_pk, using=using, raw=raw)
  File "/home/israelord/.virtualenvs/ringtu-env/local/lib/python2.7/site-packages/django/db/models/manager.py", line 215, in _insert
    return insert_query(self.model, objs, fields, **kwargs)
  File "/home/israelord/.virtualenvs/ringtu-env/local/lib/python2.7/site-packages/django/db/models/query.py", line 1673, in insert_query
    return query.get_compiler(using=using).execute_sql(return_id)
  File "/home/israelord/.virtualenvs/ringtu-env/local/lib/python2.7/site-packages/django/db/models/sql/compiler.py", line 936, in execute_sql
    for sql, params in self.as_sql():
  File "/home/israelord/.virtualenvs/ringtu-env/local/lib/python2.7/site-packages/django/db/models/sql/compiler.py", line 894, in as_sql
    for obj in self.query.objs
  File "/home/israelord/.virtualenvs/ringtu-env/local/lib/python2.7/site-packages/django/db/models/fields/__init__.py", line 304, in get_db_prep_save
    prepared=False)
  File "/home/israelord/.virtualenvs/ringtu-env/local/lib/python2.7/site-packages/django/db/models/fields/__init__.py", line 835, in get_db_prep_value
    value = self.get_prep_value(value)
  File "/home/israelord/.virtualenvs/ringtu-env/local/lib/python2.7/site-packages/django/db/models/fields/__init__.py", line 820, in get_prep_value
    value = self.to_python(value)
  File "/home/israelord/.virtualenvs/ringtu-env/local/lib/python2.7/site-packages/django/db/models/fields/__init__.py", line 788, in to_python
    parsed = parse_datetime(value)
  File "/home/israelord/.virtualenvs/ringtu-env/local/lib/python2.7/site-packages/django/utils/dateparse.py", line 67, in parse_datetime
    match = datetime_re.match(value)
TypeError: expected string or buffer

1 个答案:

答案 0 :(得分:1)

看起来您的问题不在FileField,而是在保存VoiceMessage实例时发生。

在追溯中,失败发生在FieldFile.save()

的末尾
  File "/home/israelord/.virtualenvs/ringtu-env/local/lib/python2.7/site-packages/django/db/models/fields/files.py", line 95, in save
    self.instance.save()

这意味着一切都很顺利,只有当这个方法在save()对象上调用vm时才会出现问题:

# FileField.save() calls instance.save() just before returning
# Here, self.instance is the vm object
def save(self, name, content, save=True): 
    name = self.field.generate_filename(self.instance, name) 
    self.name = self.storage.save(name, content) 
    setattr(self.instance, self.field.name, self.name) 

    # Update the filesize cache 
    self._size = content.size 
    self._committed = True 

    # Save the object because it has changed, unless save is False 
    if save: 
        self.instance.save() 

我最好的猜测是问题出在vm.date或其他DateTimeField字段,因为DateTimeField.to_python函数中引发了异常。你能检查一下msg['when']的类型吗?您也可以通过跳过实例保存步骤来确认这一点:

vm.message.save(filename, File(msg['file']), False) # Added False
msg['file'].close()
vm.save() # Error should now be raised here