Django Wagtail CSV и загрузка фотографий - команда управления

Я работаю над командой управления django/wagtail (назовем ее «file_upload»), которая делает примерно следующее:

  • возьмите аргумент «csv», который представляет собой полный путь к CSV-файлу.
  • разобрать и открыть результат с помощью csv
  • для каждой строки создайте и сохраните пользовательский объект модели изображения трясогузки (наследуя от AbstractImage, с несколькими дополнительными CharField, которые, как я думаю, не мешают мне делать то, что я хочу)

(В настоящее время упрощенный) CSV выглядит следующим образом:

1.jpg,Title 1
2.jpg,Title 2

Совсем не сложно, даже просто ... но этот аспект трясогузки, похоже, не очень документирован. Не работает следующее:

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'

Большое спасибо


person Hal    schedule 27.04.2018    source источник
comment
File(open) выглядит неправильно. Это должно быть File(f)?   -  person gasman    schedule 27.04.2018


Ответы (1)


Благодаря gasman теперь это работает. Дух.

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 сохранен и т.д. и т.п. Все хорошо.

Однако поле file для этого объекта теперь заполнено:

original_images/CFolderSubFolderSubSubFolderSubSubSubFolder1.jpg

Где CFolderSubFolderSubSubFolderSubSubSubFolder, по-видимому, является очищенной версией C:\Folder\SubFolder\SubSubFolder\SubSubSubFolder

Есть ли способ избавиться от этого (бесполезного) пути? Это, по-видимому, полный путь к файлу JPG.

Спасибо!

person Hal    schedule 27.04.2018
comment
Ответ: django_file = File(f, name=row[0]) - person Hal; 27.04.2018