【问题标题】:Trying to save multiple files in Django 2 Admin尝试在 Django 2 Admin 中保存多个文件
【发布时间】:2018-12-09 19:37:57
【问题描述】:

我已阅读有关使用 django 2 管理员保存多个文件的各种帖子,但我仍然无法使用它。

我的模特:

class Document(Model):
    document_id = models.AutoField(primary_key=True)
    document_state = models.IntegerField(choices=DOCUMENT_STATE, default=PRIVATE, verbose_name="state")
    documentType_id = models.ForeignKey(DocumentType, on_delete=models.CASCADE, verbose_name="document type", )
    created = models.DateTimeField(auto_now_add=True, editable=False, verbose_name="date created")
    updated = models.DateTimeField(auto_now=True, editable=False, verbose_name="last update")
    storage_file_name = models.FileField('File name', upload_to=unique_file_path)
    thumb_storage = models.FileField(editable=False,)
    original_file_name = models.CharField(editable=False, max_length=200)
    computed_sha256 = models.CharField(editable=False, max_length=64)

我在 Document admin 中创建了自己的字段,因此我在该字段中添加了“multiple”关键字。 storage_file_name 字段在管理员创建文档页面中如下所示:

<label class="required" for="id_storage_file_name">File name:</label>
    <input type="file" name="storage_file_name" multiple required id="id_storage_file_name" />

我在 DocumentAdmin 类的 save_model 中有这个:

def save_model(self, request, obj, form, change):
        logger.debug("save_model START")
        logger.debug("obj=%s, change=%s" % (obj, change))
        if (form.is_valid()):
            logger.debug("\tvalid form")
            logger.debug("form.cleaned_data=%s",form.cleaned_data)
            obj.metadata = form.cleaned_data['metadata']
        logger.debug("files=%s" % request.FILES.getlist('storage_file_name'))
        files = request.FILES.getlist('storage_file_name')
        for f in files:
            logger.debug("storing file=%s" % f)
            obj.storage_file_name = f
            super().save_model(request, obj, form, change)
        logger.debug("save_model END")

files 有我要上传的文件的正确列表。但我似乎无法保存文件列表中的最后一项。我没有收到任何错误消息;如果所选文件未上传,则仅列出列表中的前 n 个图像。

如果可以避免的话,我宁愿不在我的应用程序中包含许多 django-multiple-file-upload 应用程序之一。我宁愿了解我做错了什么并修复它!

谢谢!

标记

PS 在尝试了不同的方法后,这终于奏效了。请注意,没有调用 super.save_model,这似乎是基于 django 文档的问题。

def save_model(self, request, obj, form, change):
    logger.debug("save_model START")
    logger.debug("obj=%s, change=%s" % (obj, change))
    if (form.is_valid()):
        logger.debug("\tvalid form")
        logger.debug("form.cleaned_data=%s",form.cleaned_data)
        logger.debug("files=%s" % request.FILES.getlist('storage_file_name'))
        files = request.FILES.getlist('storage_file_name')
        for f in files:
            logger.debug("storing file=%s" % f)
            obj2 = Document()
            obj2.storage_file_name = f
            obj2.metadata = form.cleaned_data['metadata']
            obj2.document_state = form.cleaned_data['document_state']
            obj2.documentType_id = form.cleaned_data['documentType_id']
            obj2.save()
    logger.debug("save_model END")

字段 metadata、document_state 和 documentType_id 都在 form.cleaned_data 字典中。

这是上传多个文件的首选方式吗?

谢谢!

标记

【问题讨论】:

    标签: django django-models django-admin


    【解决方案1】:

    save_model 方法中,您有 obj 参数,它是从 django admin 的更改页面保存/更改的对象。

    另一方面,您尝试保存模型的多个对象。因此,在 for 循环中,相同的对象被传递给 super 调用,并且正在为其他图像进行更新。

    因此,您只看到最后一张图像被保存到数据库中。 super 调用没有任何问题。

    def save_model(self, request, obj, form, change):
        ...
        for f in files:
            logger.debug("storing file=%s" % f)
            # same object getting updated.
            obj.storage_file_name = f
            super().save_model(request, obj, form, change)
        logger.debug("save_model END")
    

    所以你必须每次在 for 循环中创建一个新对象,然后保存它。

    希望它能消除你的疑虑。

    【讨论】:

    • 好的。我是否应该在上面 PS 的代码中使用 super().save_model(request, obj2, form, change) 而不是 obj2.save?我查看了 save_model 的源代码,它所做的只是 obj.save()。
    • 由于与常规流程相反,您一次保存多个对象,因此最好使用您已经完成的自定义 save_model。
    猜你喜欢
    • 1970-01-01
    • 2018-10-12
    • 2012-10-02
    • 2022-09-30
    • 2013-12-08
    • 1970-01-01
    • 2020-09-11
    • 2017-10-21
    • 2011-05-16
    相关资源
    最近更新 更多