如何在Django中显示多文件上传表格的进度条?

发布于 2025-01-31 16:03:32 字数 3186 浏览 0 评论 0原文

我正在开发一个应用程序,要求用户上传多个文件/文件类型/子文件夹的大量目录。它将处理10个用户的10可能的GB,因此在上传时显示进度条将非常有帮助,以告知用户大量文件的进度。

我目前的设置是基于对另一个问题的以下答案:

这是一个简化的设置:

models.py:

class Feed(models.Model):
user=models.ForeignKey(User, on_delete=models.CASCADE)
text=models.TextField(blank=False, max_length=500)

class FeedFile(models.Model):
file = models.FileField(upload_to="files/%Y/%m/%d")
feed = models.ForeignKey(Feed, on_delete=models.CASCADE)

forms.py:

class FeedModelForm(forms.ModelForm):
    class Meta:
        model = Feed
        fields = ['text']

class FileModelForm(forms.ModelForm):
    class Meta:
        model = FeedFile
        fields = ['file']
        widgets = {
            'file': ClearableFileInput(attrs={'multiple': True}),
        }
        # widget is important to upload multiple files

views.py:

def upload_files_view(request):
    user = request.user
    if request.method == 'POST':
        form = FeedModelForm(request.POST)
        file_form = FileModelForm(request.POST, request.FILES)
        files = request.FILES.getlist('file')  # field name in model

        if form.is_valid() and file_form.is_valid():
            feed_instance = form.save(commit=False)
            feed_instance.user = user
            feed_instance.save()

            total_files = len(files)  # Get the number of files in 'files'
            files_count = 0  # Use to show user the progress out of 'total_files'

            for f in files:
                file_instance = FeedFile(file=f, user=use, feed=feed_instance)
                file_instance.save()

                progress = f"{total_files}/{files_count}"
                # render(request, 'some_folder/upload_progress.html', {'file_form': file_form, 'form': form, 'progress': progress})  # somehow refresh the page showing 'progress' in an html tag? 
                files_count += 1

            return redirect('upload_success_page')
    else:
        form = FeedModelForm()
        file_form = FileModelForm()
        return render(request, 'some_folder/file_upload.html', {'file_form': file_form, 'form': form})

我的最终目标是获取总文件计数(如上面的views.py文件显示),检测当前正在上传的文件,然后返回该文件值到模板,供用户以某种方式监视。 (您可以看到我在views.py文件中尝试的内容,但是此方法由于多种原因而无法使用。)

我的问题: 在上传文件时,如何获取此信息,并将其发送到用户正在查看的模板/页面?

这是Google Drive文件夹上传进度栏的一个示例,正在上传1185个文件的文件夹,当前进度为11:

”

在我完成的研究方面,我发现了许多有关使用Ajax的类似问题。所有其他Stackexchagne的问题都非常旧,要么没有答案,而且没有太大帮助。这篇文章似乎很有希望,但是看来代码未完成,我无法正常工作: https://anshu-dev.medium.com/file-upload-ploard-progress-bar-usis-django-and-django-and-ajango-and-ajax-ba4eb7482d9c

in我的看法理想的方法将完全使用django views.py,但是我不确定是否可能或如何做到这一点。

非常感谢我能得到的任何帮助,谢谢您的宝贵时间!

I'm developing an application that requires users to upload a massive directory of multiple files/file types/subfolders. It will be handling 10's possibly 100s of GB per user, so having a progress bar displayed while uploading will be very helpful in informing the user the progress of the massive files.

My current setup is based on the following answer to another question: https://stackoverflow.com/a/52016594/15739035

Here is a simplified setup:

models.py:

class Feed(models.Model):
user=models.ForeignKey(User, on_delete=models.CASCADE)
text=models.TextField(blank=False, max_length=500)

class FeedFile(models.Model):
file = models.FileField(upload_to="files/%Y/%m/%d")
feed = models.ForeignKey(Feed, on_delete=models.CASCADE)

forms.py:

class FeedModelForm(forms.ModelForm):
    class Meta:
        model = Feed
        fields = ['text']

class FileModelForm(forms.ModelForm):
    class Meta:
        model = FeedFile
        fields = ['file']
        widgets = {
            'file': ClearableFileInput(attrs={'multiple': True}),
        }
        # widget is important to upload multiple files

views.py:

def upload_files_view(request):
    user = request.user
    if request.method == 'POST':
        form = FeedModelForm(request.POST)
        file_form = FileModelForm(request.POST, request.FILES)
        files = request.FILES.getlist('file')  # field name in model

        if form.is_valid() and file_form.is_valid():
            feed_instance = form.save(commit=False)
            feed_instance.user = user
            feed_instance.save()

            total_files = len(files)  # Get the number of files in 'files'
            files_count = 0  # Use to show user the progress out of 'total_files'

            for f in files:
                file_instance = FeedFile(file=f, user=use, feed=feed_instance)
                file_instance.save()

                progress = f"{total_files}/{files_count}"
                # render(request, 'some_folder/upload_progress.html', {'file_form': file_form, 'form': form, 'progress': progress})  # somehow refresh the page showing 'progress' in an html tag? 
                files_count += 1

            return redirect('upload_success_page')
    else:
        form = FeedModelForm()
        file_form = FileModelForm()
        return render(request, 'some_folder/file_upload.html', {'file_form': file_form, 'form': form})

My end goal is to get the total file count (like the above views.py file shows), detect what file is currently being uploaded, and return that value to a template for the user to monitor somehow. (You can see what I've attempted above in the views.py file, however this method doesn't work for a number of reasons.)

My question:
How do I get this information while the files are being uploaded, and send it to the template/page the user is viewing?

Here is an example of the Google Drive folder upload progress bar, a folder of 1185 files is being uploaded and the current progress is 11:

An example of the Google Drive Folder upload UI element showing a folder of 1185 files is being uploaded and the current progress is 11

In terms of research I've done, I've found many similar questions about using Ajax. All of the other StackExchagne questions are either really old or don't have an answer and weren't much help. This article seemed promising, however it appears that the code is unfinished, and I couldn't get it to work: https://anshu-dev.medium.com/file-upload-progress-bar-using-django-and-ajax-ba4eb7482d9c

In my opinion the ideal method would be entirely using Django views.py, however I'm not entirely sure if or how this would be possible.

I really appreciate any help I can get, thank you for your time!

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。
列表为空,暂无数据
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文