Progress bar for FileField upload in a ModelForm (

2019-02-15 19:45发布

I'm looking for some pointers to implementing a file upload progress bar that gives feedback about the current status of the upload of a FileField inside a ModelForm.

My ModelForm has got a lot of fields (not only FileField) and I would like to show a live feedback of the progress with a progress bar.

Thanks.

1条回答
可以哭但决不认输i
2楼-- · 2019-02-15 20:24

Here is my solution to the problem: django-smartfields, this app can take care of reporting progress, convert images or videos, clean up old files and more. It has some requirements for progress reporting:

I am working on documentation for django-smartfields right now, but this portion of the app is still not documented, but here is how you would use it.

from django.db import models
from django.conf import settings
from smartfields import fields

class FileModel(models.Model):
    user = models.ForeignKey(settings.AUTH_USER_MODEL, editable=False)
    file = fields.FileField(uploadTo='files')
    # other fields ....
    parent_field_name = 'user'

    def has_upload_permission(self, user, field_name=None):
        return user == self.user

Now in forms.py:

from django import forms
from myapp.models import FileModel
from crispy_forms.helper import FormHelper
from crispy_forms.layout import Layout
from smartfields.crispy.layout import FileField

class FileForm(forms.ModelForm):

    class Meta:
        model = FileModel
        fields = ('file', other fields...)

    @property
    def file_upload_url(self):
        return reverse("smartfields:upload", kwargs={
            'app_label': 'test_app',
            'model': FileModel.__name__,
            'field_name': 'file',
            'pk': self.instance.pk,
            'parent_field_name': 'user'
            'parent_pk': self.instance.user.pk
        })


    def __init__(self, *args, **kwargs):
        super(FileForm, self).__init__(*args, **kwargs)
        self.helper = FormHelper(self)
        self.helper.form_tag = False
        self.helper.layout = Layout(
            FileField('file', plupload_options={
                'url': self.file_upload_url,
                'filters': {
                    'max_file_size': "20mb",
                    'mime_types': [{'title': "Documents",
                                    'extensions': "pdf,doc"}]
            }}))

Nothing special needs to be done in the views.py, except that 'file_form' should be in the context. Make sure smartfields are in INSTALLED_APPS and urls have url(r'^smartfields/', include('smartfields.urls', namespace='smartfields')), in them or you can create a customized upload view, by extending smartfields.views.FielUpload.

In the template:

{% load static crispy_forms_tags %}
<link rel="stylesheet" href="{% static 'bootstrap3/css/bootstrap.min.css' %}">
<link rel="stylesheet" href="{% static 'bootstrap3/css/bootstrap-theme.min.css' %}">
<link rel="stylesheet" href="{% static 'css/smartfields.css' %}">

<script type="text/javascript" src="//ajax.googleapis.com/ajax/libs/jquery/1.11.0/jquery.min.js"></script>
<script type="text/javascript" src="{% static 'bootstrap3/js/bootstrap.min.js' %}"></script>
<script type="text/javascript" src="{% static 'plupload/js/plupload.full.min.js' %}"></script>
<script type="text/javascript" src="{% static 'js/bootbox.min.js' %}"></script>
<script type="text/javascript" src="{% static 'js/smartfields.js' %}"></script>

<form method="POST">
  {% crispy file_form %}
  <input class="btn btn-default" type="submit" name="btn_save" value="Save">
</form>

Let me know if you have any questions or if it doesn't work for some reason. Make sure you use version from github, javascript file on pypi is outdated.

查看更多
登录 后发表回答