我重写模型的save()
方法来处理目录。
我覆盖的save()
方法如下:
def save(self, *args, **kwargs):
book_dir = os.path.join(MEDIA_ROOT, self.title)
# check that at least one file is loading
if all([self.pdf, self.fb2, self.epub]):
raise ValidationError("At least 1 file should be uploaded!")
# create book's directory if it not exists
if os.path.exists(book_dir):
raise ValidationError("This book is already exists!")
else:
os.mkdir(book_dir)
# assign uploading files storage
for x in [self.image, self.pdf, self.fb2, self.epub]:
x.storage = book_dir
super().save(*args, **kwargs) # Call the "real" save() method.
一切顺利,直到最后一行。 Django给我AttributeError: 'str' object has no attribute 'save'
错误。
UPD 1: 添加了完整模型
class Book(models.Model):
title = models.CharField(
verbose_name="Book title",
max_length=75,
null=False,
unique=True,
)
year_pub = models.IntegerField(
verbose_name="Year published",
null=False
)
image = models.ImageField(
verbose_name="Preview image",
null=False
)
pdf = models.FileField(
verbose_name="PDF file",
null=True,
blank=True,
validators=[validators.validate_book_ext]
)
fb2 = models.FileField(
verbose_name="FB2 file",
null=True,
blank=True,
validators=[validators.validate_book_ext]
)
epub = models.FileField(
verbose_name="EPUB file",
null=True,
blank=True,
validators=[validators.validate_book_ext]
)
def save(self, *args, **kwargs):
book_dir = os.path.join(MEDIA_ROOT, self.title)
# check that at least one file is loading
if all([self.pdf, self.fb2, self.epub]):
raise ValidationError("At least 1 file should be uploaded!")
# create book's directory if it not exists
if os.path.exists(book_dir):
raise ValidationError("This book is already exists!")
else:
os.mkdir(book_dir)
# assign uploading files storage
for x in [self.image, self.pdf, self.fb2, self.epub]:
x.storage = book_dir
super().save(*args, **kwargs) # Call the "real" save() method.
UPD 2: 添加了回溯
Traceback (most recent call last):
File "c:\Users\yuyuko\Documents\dev\project3\env\lib\site-packages\django\core\handlers\exception.py", line 34, in inner
response = get_response(request)
File "c:\Users\yuyuko\Documents\dev\project3\env\lib\site-packages\django\core\handlers\base.py", line 115, in _get_response
response = self.process_exception_by_middleware(e, request)
File "c:\Users\yuyuko\Documents\dev\project3\env\lib\site-packages\django\core\handlers\base.py", line 113, in _get_response
response = wrapped_callback(request, *callback_args, **callback_kwargs)
File "c:\Users\yuyuko\Documents\dev\project3\env\lib\site-packages\django\contrib\admin\options.py", line 606, in wrapper
return self.admin_site.admin_view(view)(*args, **kwargs)
File "c:\Users\yuyuko\Documents\dev\project3\env\lib\site-packages\django\utils\decorators.py", line 142, in _wrapped_view
response = view_func(request, *args, **kwargs)
File "c:\Users\yuyuko\Documents\dev\project3\env\lib\site-packages\django\views\decorators\cache.py", line 44, in _wrapped_view_func
response = view_func(request, *args, **kwargs)
File "c:\Users\yuyuko\Documents\dev\project3\env\lib\site-packages\django\contrib\admin\sites.py", line 223, in inner
return view(request, *args, **kwargs)
File "c:\Users\yuyuko\Documents\dev\project3\env\lib\site-packages\django\contrib\admin\options.py", line 1634, in add_view
return self.changeform_view(request, None, form_url, extra_context)
File "c:\Users\yuyuko\Documents\dev\project3\env\lib\site-packages\django\utils\decorators.py", line 45, in _wrapper
return bound_method(*args, **kwargs)
File "c:\Users\yuyuko\Documents\dev\project3\env\lib\site-packages\django\utils\decorators.py", line 142, in _wrapped_view
response = view_func(request, *args, **kwargs)
File "c:\Users\yuyuko\Documents\dev\project3\env\lib\site-packages\django\contrib\admin\options.py", line 1522, in changeform_view
return self._changeform_view(request, object_id, form_url, extra_context)
File "c:\Users\yuyuko\Documents\dev\project3\env\lib\site-packages\django\contrib\admin\options.py", line 1561, in _changeform_view
self.save_model(request, new_object, form, not add)
File "c:\Users\yuyuko\Documents\dev\project3\env\lib\site-packages\django\contrib\admin\options.py", line 1088, in save_model
obj.save()
File "C:\Users\yuyuko\Documents\dev\project3\djangoApp\library\models.py", line 58, in save
super().save(*args, **kwargs) # Call the "real" save() method.
File "c:\Users\yuyuko\Documents\dev\project3\env\lib\site-packages\django\db\models\base.py", line 741, in save
force_update=force_update, update_fields=update_fields)
File "c:\Users\yuyuko\Documents\dev\project3\env\lib\site-packages\django\db\models\base.py", line 779, in save_base
force_update, using, update_fields,
File "c:\Users\yuyuko\Documents\dev\project3\env\lib\site-packages\django\db\models\base.py", line 870, in _save_table
result = self._do_insert(cls._base_manager, using, fields, update_pk, raw)
File "c:\Users\yuyuko\Documents\dev\project3\env\lib\site-packages\django\db\models\base.py", line 908, in _do_insert
using=using, raw=raw)
File "c:\Users\yuyuko\Documents\dev\project3\env\lib\site-packages\django\db\models\manager.py", line 82, in manager_method
return getattr(self.get_queryset(), name)(*args, **kwargs)
File "c:\Users\yuyuko\Documents\dev\project3\env\lib\site-packages\django\db\models\query.py", line 1186, in _insert
return query.get_compiler(using=using).execute_sql(return_id)
File "c:\Users\yuyuko\Documents\dev\project3\env\lib\site-packages\django\db\models\sql\compiler.py", line 1334, in execute_sql
for sql, params in self.as_sql():
File "c:\Users\yuyuko\Documents\dev\project3\env\lib\site-packages\django\db\models\sql\compiler.py", line 1278, in as_sql
for obj in self.query.objs
File "c:\Users\yuyuko\Documents\dev\project3\env\lib\site-packages\django\db\models\sql\compiler.py", line 1278, in <listcomp>
for obj in self.query.objs
File "c:\Users\yuyuko\Documents\dev\project3\env\lib\site-packages\django\db\models\sql\compiler.py", line 1277, in <listcomp>
[self.prepare_value(field, self.pre_save_val(field, obj)) for field in fields]
File "c:\Users\yuyuko\Documents\dev\project3\env\lib\site-packages\django\db\models\sql\compiler.py", line 1228, in pre_save_val
return field.pre_save(obj, add=True)
File "c:\Users\yuyuko\Documents\dev\project3\env\lib\site-packages\django\db\models\fields\files.py", line 288, in pre_save
file.save(file.name, file.file, save=False)
File "c:\Users\yuyuko\Documents\dev\project3\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)
AttributeError: 'str' object has no attribute 'save'
[19/Sep/2019 23:11:03] "POST /admin/library/book/add/ HTTP/1.1" 500 181939
答案 0 :(得分:0)
所以,我错过了另外一种要覆盖的存储方法。
现在,我的覆盖循环存储位置运行良好,看起来像这样:
# rename and edit storage location of books to book_dir
for field in [self.image, self.pdf, self.fb2, self.epub]:
field.storage.location = book_dir