使用Python脚本将文件保存到Django中的上载字段

时间:2014-07-25 16:20:26

标签: python django

构建应用程序以列出检查报告。实际检验报告将可供下载。使用django-db-file-storage将报告保存到数据库。

要处理的大量记录,因此编写脚本以批量执行所有操作。在manage.py shell中进行测试会引发错误。

from django.core.files.storage import default_storage
from django.core.files.base import ContentFile
from inspections.models import InspectionInformation, RestaurantInformation

file = open('/docs/Data/2011/12/12-07-11_1498.pdf', 'r').read()

InspectionInformation(
                insp_rest_permit=RestaurantInformation.objects.get(rest_permit=int('1814')),
                insp_date='2011-12-12',
                insp_score='100',
                insp_inspector='Philip',
                insp_report=default_storage.save('report.pdf', ContentFile(file))
            ).save()

回溯

Traceback (most recent call last):
  File "<console>", line 6, in <module>
  File "/venv/lib/python2.7/site-packages/django/core/files/storage.py", line 48, in save
    name = self.get_available_name(name)
  File "/venv/lib/python2.7/site-packages/django/core/files/storage.py", line 74, in get_available_name
    while self.exists(name):
  File "/venv/lib/python2.7/site-packages/db_file_storage/storage.py", line 77, in exists
    model_class_path, content_field, filename_field, mimetype_field, filename = name.split('/')
ValueError: need more than 1 value to unpack

模型

from django.db import models


class RestaurantInformation(models.Model):
    rest_permit = models.IntegerField(unique=True, verbose_name='Permit')
    rest_name = models.CharField(max_length=200, verbose_name='Name')
    rest_address = models.CharField(max_length=200, verbose_name='Address')
    rest_city = models.CharField(max_length=100, verbose_name='City')
    rest_zip = models.IntegerField(verbose_name='Zip Code')
    rest_owner = models.CharField(max_length=200, verbose_name='Owner')
    rest_latitude = models.CharField(max_length=40, verbose_name='Latitude')
    rest_longitude = models.CharField(max_length=40, verbose_name='Longitude')

    class Meta:
        ordering = ['rest_name']

    def __unicode__(self):
        return self.rest_name + ', ' + self.rest_address + ', ' + self.rest_city


class InspectionInformation(models.Model):
    insp_rest_permit = models.ForeignKey(RestaurantInformation, null=False, to_field='rest_permit')
    insp_score = models.DecimalField(verbose_name='Score', decimal_places=2, max_digits=5)
    insp_date = models.DateField(verbose_name='Date')
    insp_inspector = models.CharField(max_length=200, verbose_name='Inspector')
    insp_report = models.FileField(upload_to='restaurants.InspectionFile/bytes/filename/mimetype',
                                   blank=True, null=True, verbose_name='Inspection Report')

    class Meta:
        unique_together = ("insp_rest_permit", "insp_score", "insp_date")
        ordering = ['insp_date']


class InspectionFile(models.Model):
    bytes = models.TextField()
    filename = models.CharField(max_length=255)
    mimetype = models.CharField(max_length=50)

1 个答案:

答案 0 :(得分:1)

1.看起来像db_file_storage.storage.save()期望它们指定的自定义格式与模型和文件名一起使用,例如: “console.ConsolePicture / bytes / filename / mimetype”+ filename。

所以对你的例子而不是

'report.pdf' 

它将是

'restaurants.InspectionFile/bytes/filename/mimetype/report.pdf'

我查看了文档并且不清楚为什么这样做是因为这违反了DRY,让你输入两次相同的东西,但是他们在整个DatabaseFileStorage类中使用相同的格式。

2.看起来保存方法(第60行)中还有一个错误

mimetype = content.file.content_type

应改为

mimetype = content.content_type

你传递的文件应该是具有content_type属性的东西,所以可能是一个Django SimpleUploadedFile:

from django.core.files.uploadedfile import SimpleUploadedFile
file_ = SimpleUploadedFile('report.pdf', open('/docs/Data/2011/12/12-07-11_1498.pdf', 'r').read())  

我认为这是一个错误的原因是,当我尝试传入一个看起来像“content.file.content_type”的模拟对象时,我后来得到了一个Python核心库异常。