Django Wagtail CSV和照片“上传"-管理命令
我正在执行django/wagtail管理命令(我们称其为"file_upload"),该命令大致执行以下操作:
I am working on a django/wagtail management command (let's call it "file_upload") that does roughly the following:
- 采用"csv"参数,它是CSV文件的完整路径.
- 使用
csv
解析并打开结果 - 为每行创建并保存一个自定义的Wagtail Image模型对象(从
AbstractImage
继承,带有一些额外的CharField
,我认为这不会阻止我执行操作我想做)
- take "csv" argument, which is a full path to a CSV file.
- parse and open the result using
csv
- for each row, create and save a custom Wagtail Image model object (inheriting from
AbstractImage
, with a few extraCharField
that I do not think prevent me from doing what I want to do)
(当前简化的)CSV如下所示:
The (currently simplified) CSV looks like this:
1.jpg,Title 1
2.jpg,Title 2
一点也不复杂,甚至简单明了……但是这种Wa的方面似乎没有得到充分的记载.以下内容不起作用:
Does not complicated at all, even straightforward ... but this Wagtail aspect of things does not seem to be heavily documented. The following does not work:
import csv
import argparse
import os, sys
from django.core.files import File
from django.core.management.base import BaseCommand
from django.utils import timezone
from django.conf import settings
from custom_photo.models import CustomPhoto
class Command(BaseCommand):
def add_arguments(self, parser):
parser.add_argument('--csv', nargs='?', type=argparse.FileType('r'))
def handle(self, *args, **options):
path = os.path.dirname(os.path.realpath(options['csv'].name))
with options['csv'] as csvfile:
readCSV = csv.reader(csvfile, delimiter=',')
for row in readCSV:
# the file full path assumes everything is flat in the same folder
with open('%s/%s' %(path, row[0]), 'rb') as f:
django_file = File(open)
print(django_file)
photo = CustomPhoto()
photo.title=row[1]
# three arguments:
# 1) relative path inside MEDIA_ROOT
# 2) the django File object
# 3) Whether or not we want to save the photo object after the image is saved
photo.file.save(row[0], django_file, True)
print(photo.__dict__)
运行如下:
python manage.py cca_photo_import --csv=C:\path\to\file\list.csv
并抛出以下错误:
Traceback (most recent call last):
File "manage.py", line 10, in <module>
execute_from_command_line(sys.argv)
File "<snip>env\lib\site-packages\django\core\management\__init__.py", line 371, in execute_from_command_line
utility.execute()
File "<snip>env\lib\site-packages\django\core\management\__init__.py", line 365, in execute
self.fetch_command(subcommand).run_from_argv(self.argv)
File "<snip>env\lib\site-packages\django\core\management\base.py", line 288, in run_from_argv
self.execute(*args, **cmd_options)
File "<snip>env\lib\site-packages\django\core\management\base.py", line 335, in execute
output = self.handle(*args, **options)
File "<snip>cca\cca_photo\management\commands\cca_photo_import.py", line 43, in handle
photo.file.save(row[0], django_file, True)
File "<snip>env\lib\site-packages\django\db\models\fields\files.py", line 87, in save
self.name = self.storage.save(name, content, max_length=self.field.max_length)
File "<snip>env\lib\site-packages\django\core\files\storage.py", line 49, in save
return self._save(name, content)
File "<snip>env\lib\site-packages\django\core\files\storage.py", line 268, in _save
for chunk in content.chunks():
File "<snip>env\lib\site-packages\django\core\files\base.py", line 71, in chunks
data = self.read(chunk_size)
File "<snip>env\lib\site-packages\django\core\files\utils.py", line 16, in <lambda>
read = property(lambda self: self.file.read)
AttributeError: 'builtin_function_or_method' object has no attribute 'read'
非常感谢
感谢 gasman ,现在可以使用了.h
Thanks to gasman, this is now working. Duh.
import csv
import argparse
import os, sys
from django.core.files import File
from django.core.management.base import BaseCommand
from django.utils import timezone
from django.conf import settings
from custom_photo.models import CustomPhoto, CustomPhotoPlate, CustomPhotoType
class Command(BaseCommand):
def add_arguments(self, parser):
parser.add_argument('--csv', nargs='?', type=argparse.FileType('r'))
def handle(self, *args, **options):
path = os.path.dirname(os.path.realpath(options['csv'].name))
with options['csv'] as csvfile:
readCSV = csv.reader(csvfile, delimiter=',')
for row in readCSV:
photo_path = '%s/%s' %(path, row[0])
with open(photo_path, 'rb') as f:
django_file = File(f)
photo = CustomPhoto()
photo.title=row[1]
photo.file = django_file
photo.save()
print(photo.__dict__)
保存了 photo
对象,等等,等等.
The photo
object is saved, etc, etc. All good.
但是,该对象的 file
字段现在填充:
However, the file
field for that object is now populated with:
original_images/CFolderSubFolderSubSubFolderSubSubSubFolder1.jpg
其中CFolderSubFolderSubSubFolderSubSubSubFolder显然是 C:\ Folder \ SubFolder \ SubSubFolder \ SubSubSubFolder
Where CFolderSubFolderSubSubFolderSubSubSubFolder is apparently the cleaned version of C:\Folder\SubFolder\SubSubFolder\SubSubSubFolder
有什么方法可以摆脱这种(无用的)路径?显然,这是JPG文件的完整路径.
Any way to get rid of this (useless) path? Which is apparently the full path to the JPG file.
谢谢!