Python Django在重写save方法时出错

Python Django在重写save方法时出错,python,django,Python,Django,我重写了模型的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

我重写了模型的
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.
# 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
直到最后一行,一切都很顺利。Django给了我
属性错误:“str”对象没有属性“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
回溯(最近一次呼叫最后一次):
文件“c:\Users\yuyuko\Documents\dev\project3\env\lib\site packages\django\core\handlers\exception.py”,第34行,在内部
响应=获取响应(请求)
文件“c:\Users\yuyuko\Documents\dev\project3\env\lib\site packages\django\core\handlers\base.py”,第115行,在get响应中
response=self.process\u异常\u由\u中间件(e,请求)
文件“c:\Users\yuyuko\Documents\dev\project3\env\lib\site packages\django\core\handlers\base.py”,第113行,在get响应中
响应=包装的回调(请求,*回调参数,**回调参数)
文件“c:\Users\yuyuko\Documents\dev\project3\env\lib\site packages\django\contrib\admin\options.py”,第606行,在包装器中
返回self.admin\u site.admin\u视图(视图)(*args,**kwargs)
文件“c:\Users\yuyuko\Documents\dev\project3\env\lib\site packages\django\utils\decorators.py”,第142行,在包装视图中
响应=查看功能(请求,*args,**kwargs)
文件“c:\Users\yuyuko\Documents\dev\project3\env\lib\site packages\django\views\decorators\cache.py”,第44行,在“包装视图”函数中
响应=查看功能(请求,*args,**kwargs)
文件“c:\Users\yuyuko\Documents\dev\project3\env\lib\site packages\django\contrib\admin\sites.py”,第223行,位于内部
返回视图(请求、*args、**kwargs)
文件“c:\Users\yuyuko\Documents\dev\project3\env\lib\site packages\django\contrib\admin\options.py”,第1634行,在添加视图中
返回self.changeform\u视图(请求、无、表单url、额外上下文)
文件“c:\Users\yuyuko\Documents\dev\project3\env\lib\site packages\django\utils\decorators.py”,第45行,在\u包装中
返回边界_方法(*args,**kwargs)
文件“c:\Users\yuyuko\Documents\dev\project3\env\lib\site packages\django\utils\decorators.py”,第142行,在包装视图中
响应=查看功能(请求,*args,**kwargs)
文件“c:\Users\yuyuko\Documents\dev\project3\env\lib\site packages\django\contrib\admin\options.py”,第1522行,在changeform\u视图中
返回self.\u changeform\u视图(请求、对象id、表单url、额外上下文)
文件“c:\Users\yuyuko\Documents\dev\project3\env\lib\site packages\django\contrib\admin\options.py”,第1561行,在变更表单视图中
self.save_模型(请求、新_对象、表单、非添加)
文件“c:\Users\yuyuko\Documents\dev\project3\env\lib\site packages\django\contrib\admin\options.py”,第1088行,保存模式
obj.save()
文件“C:\Users\yuyuko\Documents\dev\project3\djangoApp\library\models.py”,第58行,保存
super().save(*args,**kwargs)#调用“real”save()方法。
文件“c:\Users\yuyuko\Documents\dev\project3\env\lib\site packages\django\db\models\base.py”,第741行,保存
强制更新=强制更新,更新字段=更新字段)
文件“c:\Users\yuyuko\Documents\dev\project3\env\lib\site packages\django\db\models\base.py”,第779行,在save\u base中
强制更新,使用,更新字段,
文件“c:\Users\yuyuko\Documents\dev\project3\env\lib\site packages\django\db\models\base.py”,第870行,在保存表格中
结果=self.\u do\u insert(cls.\u base\u manager,using,fields,update\u pk,raw)
文件“c:\Users\yuyuko\Documents\dev\project3\env\lib\site packages\django\db\models\base.py”,第908行,插入
使用=使用,原始=原始)
文件“c:\Users\yuyuko\Documents\dev\project3\env\lib\site packages\django\db\models\manager.py”,第82行,在manager\u方法中
返回getattr(self.get_queryset(),name)(*args,**kwargs)
文件“c:\Users\yuyuko\Documents\dev\project3\env\lib\site packages\django\db\models\query.py”,第1186行,插入
return query.get\u编译器(using=using).execute\u sql(return\u id)
文件“c:\Users\yuyuko\Documents\dev\project3\env\lib\site packages\django\db\models\sql\compiler.py”,第1334行,在execute\U sql中
对于sql,self.as_sql()中的参数为:
as\U sql中的文件“c:\Users\yuyuyuko\Documents\dev\project3\env\lib\site packages\django\db\models\sql\compiler.py”,第1278行
对于self.query.objs中的obj
文件“c:\Users\yuyuko\Documents\dev\project3\env\lib\site packages\django\db\models\sql\compiler.py”,第1278行,在
对于self.query.objs中的obj
文件“c:\Users\yuyuko\Documents\dev\project3\env\lib\site packages\django\db\models\sql\compiler.py”,第1277行,在
[self.prepare_值(字段,self.pre_保存值(字段,对象))用于字段中的字段]
文件“c:\Users\yuyuko\Documents\dev\project3\env\lib\site packages\django\db\models\sql\compiler.py”,第1228行,保存前
返回字段。预保存(obj,add=True)
文件“c:\Users\yuyuko\Documents\dev\project3\env\lib\site packages\django\db\models\fields\files.py”,第288行,预保存
file.save(file.name,file.file,save=False)
文件“c:\Users\yuyuko\Documents\dev\project3\env\lib\site packages\django\db\models\fields\files.py”,第87行,保存
self.name=self.storage.save(名称、内容、最大长度=self.field.max_长度)
AttributeError:“str”对象没有属性“save”
[2019年9月19日23:11:03]“POST/admin/library/book/add/HTTP/1.1”500 181939

因此,我又错过了一种要覆盖的存储方法

现在,我的覆盖循环存储位置运行良好,如下所示:

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.
# 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

您确定错误指向该特定行吗?而不是代码中的其他地方?无论如何,您应该在字段的验证器中执行此操作。您可以发布完整的类以及您正在调用的。保存吗?@IşıkKaplan我使用vscode中的调试器通过了方法。在
super()之后。保存(…)
我什么都没有。请将完整的错误回溯添加到您的问题中!我不知道你在这里干什么。为什么要将字符串指定为这些字段的存储属性?如果你是