将许多上传的文件保存到db save()方法时,仅对查询中的最后一个文件有效

时间:2019-07-14 21:48:01

标签: django python-3.x django-views

我正在使用CreateView,并且在模板中,我正在上传多个文件以存储在数据库中。我通过files = self.request.FILES.getlist('file')从请求中获取了所有文件,并将其循环以为每个文件创建一个对象。但是,对象创建仅适用于列表中的最后一个对象。

def form_valid(self, form):
    files = self.request.FILES.getlist('file')
    allowed_file_extensions = ['xls', 'xlsx', 'doc', 'docx', 'pdf']
    for file in files:
        file_converted_to_string = str(file)
        file_regex = re.search(r"([a-zA-Z0-9-_\s]+)[.](\w+?)$", file_converted_to_string)
        file_name, file_extension = file_regex.group(1), file_regex.group(2)
        if file_extension in allowed_file_extensions:
            self.object = form.save(commit=False)
            self.object.file = file
            self.object.file_name = file_name
            self.object.file_extension = file_extension
            self.object.department_belonged = self.request.user.profile.department
            print(self.request.user.profile.department)
            self.object.creator = self.request.user
            self.object.save()
    return super().form_valid(form)

当我替换时,更有趣:

self.object = form.save(commit=False)
self.object.file = file
self.object.file_name = file_name
self.object.file_extension = file_extension
self.object.department_belonged = self.request.user.profile.department
self.object.creator = self.request.user
self.object.save()

具有:

self.model.objects.create(file=file,
                          file_name=file_name,
                          file_extension=file_extension,
                          department_belonged=self.request.user.profile.department,
                          creator=self.request.user)

它为列表中的每个文件创建一个新对象,但在models.py中的upload_to函数中引发错误。

file = models.FileField(upload_to=file_path)

def file_path(instance, filename):
    return f'{instance.creator.profile.department}/user_{instance.creator.id}/{filename}'

错误:

  

异常值:'NoneType'对象没有属性'profile'

1 个答案:

答案 0 :(得分:0)

在第一个示例中,您继续对每个文件对象使用self.object。这将在每次保存时继续覆盖相同的对象。因此,在每次保存时,您都在更新现有的数据库行。

对于使用self.model.objects.create(file=file,....的方法,在保存实例之前,没有与实例关联的creator,并且由于此方法绕过使用对象(从内存中),因此将不起作用。我建议尝试:

obj = self.model(
    file=file,
    file_name=file_name,
    file_extension=file_extension,
    department_belonged=self.request.user.profile.department,
    creator=self.request.user
)
obj.save()

这是将在调用file_path之前创建对象并允许引用的对象。