Django Views FILES Upload In-memory & Disk Upload process

||
Posted 3 years, 11 months ago
||
Views 1052
||
2 min read
0 reactions

In this tutorial, we are going to see about FILES upload process in Django framework. In Django FILES upload process is quite interesting.

In order to demonstrate that, we are going step by steps to understand the behaviour,

Lets create the project & app just like this,

django-admin startproject teckiy

python manage.py startapp tutorial

Now, its time to create the forms.py file in the app folder,

Now add the below code in forms.py to create the form to render it,

from django import forms

class UploadTestFileForm(forms.Form):
    title = forms.CharField(max_length=50)
    file = forms.FileField()

In Django FileField objects is used for upload the FILE type from HTML.

Add the below code in views.py

def index(request, *args, **kwargs):
    
    if request.method == 'POST':
        print(request.FILES['file'].size)
        form = UploadTestFileForm(request.POST, request.FILES)
        if form.is_valid():
            handle_uploaded_file(request.FILES)
        return HttpResponseRedirect('/')
    else:
        form = UploadTestFileForm()
    return render(request, 'tutorial/upload.html', {'form': form})

Now create upload.html,

<form method='POST' action='/' enctype="multipart/form-data">
{% csrf_token %}
{{ form }}
<button type="submit">Submit</button>
</form>

Now lets talk about MemoryFileUploadHandler and TemporaryFileUploadHandler

By default if the file size < 2.5 MB then Django store the uploaded files in In-memory before processing. If file size > 2.5 MB then it will load into disk /tmp directory.

Using Below code, we can customize the progress bar for upload,

from django.core.cache import cache
from django.core.files.uploadhandler import TemporaryFileUploadHandler



class ProgressBarUploadHandler(TemporaryFileUploadHandler):
    """
    Cache system for TemporaryFileUploadHandler
    """
    def __init__(self, *args, **kwargs):
        super(TemporaryFileUploadHandler, self).__init__(*args, **kwargs)
        self.progress_id = None
        self.cache_key = None
        self.original_file_name = None

    def handle_raw_input(self, input_data, META, content_length, boundary, encoding=None):
        self.content_length = content_length
        if 'X-Progress-ID' in self.request.GET:
            self.progress_id = self.request.GET['X-Progress-ID']
        elif 'X-Progress-ID' in self.request.META:
            self.progress_id = self.request.META['X-Progress-ID']
        if self.progress_id:
            self.cache_key = "%s_%s" % (self.request.META['REMOTE_ADDR'], self.progress_id)
            cache.set(self.cache_key, {
                'size': self.content_length,
                'received': 0
            }, 30)

    def new_file(self, field_name, file_name, content_type, content_length, charset=None, content_typ_extra=None):
        self.original_file_name = file_name

    def receive_data_chunk(self, raw_data, start):
        if self.cache_key:
            data = cache.get(self.cache_key, {})
            data['received'] += self.chunk_size
            cache.set(self.cache_key, data, 30)
        return raw_data

    def file_complete(self, file_size):
        pass

    def upload_complete(self):
        # deprecated in favor of setting an expiry time a-la-nginx
        # setting an expiry time fixes the race condition in which the last
        # progress request happens after the upload has finished meaning the
        # bar never gets to 100%
        pass
        #if self.cache_key:
        #    cache.delete(self.cache_key)

Check this Video 

Happy Coding !!!!


0 reactions

Discussion


Looking for Freelancing Jobs
Joined on April 15, 2020

Latest Videos