How to handle an uploaded file in Django to store it in the database

Viewed 3753

The users should upload files from a form (images,pdf,ms word,etc).

They should be stored in the Oracle database (blob).

In the model I used BinaryField. Besides the file, I need to store file name (works) and file extension (works) (e.g. png,jpeg,etc) and file size (need help).

However i can't figure out how to handle the uploaded file in order to store it to the database blob column. (Dummy data below works though [see res])

request.FILES['file'] is the key i think

P.S. I know it's not best practise to store static files in the database but i have to do this.

My Model:

class File(models.Model): 
    du_id = models.AutoField(primary_key=True)
    du_file = models.BinaryField()
    du_file_name = models.CharField(max_length=1000)
    du_file_extension = models.CharField(max_length=100)
    du_file_size = models.CharField(max_length=100)

forms.py:

from django import forms

class UploadFileForm(forms.Form):
    file = forms.FileField(label='Upload document')

html form:

<form method="post" action="{% url 'images:upload' %}" enctype="multipart/form-data">{% csrf_token %}    
    {{form}}
    <input type="submit" value="Upload file">
</form>

view:

from django.shortcuts import render
from images.models import File
from images.forms import UploadFileForm
from django.http import HttpResponse, HttpResponseRedirect, JsonResponse
from django.urls import reverse
from django.utils.timezone import datetime
import datetime,base64

  def file_upload(request):
    if request.method == 'POST':
        form = UploadFileForm(request.POST, request.FILES)
        if form.is_valid():
            file_name = str(form.cleaned_data['file'])
            file_name_split = file_name.split('.')
            extension = file_name_split[-1].upper()

            test_string = "test string"
            res = bytes(test_string, 'utf-8') 

            a = File.objects.create(du_file = res,du_file_name=file_name,du_file_extension=extension,
            du_file_size='1023') 

            a.save()

            return HttpResponse(file_name)
            #return HttpResponseRedirect(reverse('images:home'))
        else:
            return HttpResponse('Form is not valid!')
    else:
        return HttpResponse('Failed') 
2 Answers

You can use read() method in order to return the specified number of bytes from the file, then you can store it in the database.

Note that it's not recommended. It's better to serve static files from a seperate web server (like Nginx) or from the cloud like Amazon S3.

This method is memory hungry, so you have to make some size limitations on the front-end, like 2mb max.

If you are not using Django forms, it's fine. You can get the file like that: request.FILES.get('your_file_key_param')

def file_upload(request):
    if request.method == 'POST':
        form = UploadFileForm(request.POST, request.FILES)
        if form.is_valid():
            file = form.cleaned_data.get('your_file')
            file_bytes = file.read()
            a = File.objects.create(du_file = file_bytes ,du_file_name=file_name,du_file_extension=extension,
            du_file_size='1023') 

            a.save()

            return HttpResponse(file_name)
        else:
            return HttpResponse('Form is not valid!')
    else:
        return HttpResponse('Failed') 

You can view django docs for file uploads at here.
implementation snippets given there:

from django.http import HttpResponseRedirect
from django.shortcuts import render
from .forms import UploadFileForm

# Imaginary function to handle an uploaded file.
from somewhere import handle_uploaded_file

def upload_file(request):
    if request.method == 'POST':
        form = UploadFileForm(request.POST, request.FILES)
        if form.is_valid():
            handle_uploaded_file(request.FILES['file'])
            return HttpResponseRedirect('/success/url/')
    else:
        form = UploadFileForm()
    return render(request, 'upload.html', {'form': form})
def handle_uploaded_file(f):
    with open('some/file/name.txt', 'wb+') as destination:
        for chunk in f.chunks():
            destination.write(chunk)

As they are using the file in binary format so you should be able to use it

Related