Progress bar for FileField upload in a ModelForm (Django)

后端 未结 1 1550
忘掉有多难
忘掉有多难 2021-01-07 02:17

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.

相关标签:
1条回答
  • 2021-01-07 02:53

    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:

    • django-crispy-forms
    • jQuery
    • plupload
    • bootstrap3
    • bootbox

    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.

    0 讨论(0)
提交回复
热议问题