skip to Main Content

I’m not sure if somehow the directory is wrong or there’s just some kind of common mistake in my code, but I just am not able to save my uploaded file to a folder, or more specifically, the media folder as demonstrated in a lot of examples.

I’m just taking a text field and the file and saving it in the DB using Ajax, and it works too, except that whatever file I’m selecting, it’s not getting saved in the media folder even if I create one manually nor is it creating one on its own either. I can get this to work without Ajax but not with it. Maybe it’s something related to how I’m sending and handling data over Ajax, but I’ve gone through tons of forums to try and fix it but no results so far. I’ve double checked everything else such as the settings.py config and the libraries that I’ve imported, everything looks to be in order. I’m sharing the code below.

index.html

<body>
<div class="container-fluid">
    <div class="col-md-4">
        <form id="data" enctype="multipart/form-data">
            <label for="docn">
                <input type="text" id="docn" placeholder="Please enter document name">
            </label>

            <label for="docc">
                <input type="file" id="doc" name="docu">
            </label>

            <button type="button" onclick="enterdata()">Submit</button>

        </form>
    </div>
</div>
<script>
    function enterdata() {
        var token = '{{ csrf_token }}';
        alert('csrf generated');

        $.ajax({
            type: 'POST',
            url: '/user',
            data: {
                dcn: $('#docn').val(),
                dc: $('#doc').val(),
            },
            headers: {'X-CSRFToken': token},
            success: function () {
                alert("Added");
            }
        })

    }
</script>
</body>

views.py

from django.shortcuts import render
from django.http import HttpResponse
from fileup.models import *
from django.core.files.storage import FileSystemStorage

def insert(request):
    return render(request, 'index.html')

def testing_data(request):
    if request.method == 'POST':
        dcn1 = request.POST['dcn']
        dc = request.POST['dc']

        request_file = request.FILES['docu'] if 'docu' in request.FILES else None
        if request_file:
            fs = FileSystemStorage()
            file = fs.save(request_file.name, request_file)
            fileurl = fs.url(file)

        FileDB.objects.create(
            docname=dcn1,
            doc=dc,
        )

        return HttpResponse('')

urls.py

urlpatterns = [
    path('admin/', admin.site.urls),
    path('', insert),
    path('user', testing_data),
]
if settings.DEBUG:
    urlpatterns += static(settings.MEDIA_URL, document_root = settings.MEDIA_ROOT)

models.py

from django.db import models

class FileDB(models.Model):
    docname = models.CharField(max_length=255)
    doc = models.FileField()

settings.py config

MEDIA_ROOT = os.path.join(BASE_DIR, 'media')
MEDIA_URL = '/media/'

That’s the complete project. The end goal is to save the path and filename in the DB with the selected file uploaded in the media folder. The former is being done but with no positive results from the latter.

Thank you.

3

Answers


  1. Chosen as BEST ANSWER

    I've managed to make it work, finally. Sharing the code here for anyone else who's stuck with this issue.

    index.html

    <body>
    <div class="container-fluid">
        <div class="col-md-4">
            <form id="data">
                <label for="docn">
                    <input type="text" id="docn" placeholder="Please enter document name">
                </label>
    
                <label for="docc">
                    <input type="file" id="doc" name="docu">
                </label>
    
                <button type="button" onclick="enterdata()">Submit</button>
    
            </form>
        </div>
    </div>
    <script>
        function enterdata() {
    
            var data1 = new FormData()
            data1.append('dcn', $('#docn').val())
            data1.append('dc', $('#doc').val())
            data1.append('docf', $('#doc')[0].files[0])
    
            var token = '{{ csrf_token }}';
            alert('csrf generated');
    
            $.ajax({
                type: 'POST',
                url: '/user',
                data: data1,
                processData: false,
                contentType: false,
                headers: {'X-CSRFToken': token},
                success: function () {
                    alert("Added");
                }
            })
    
        }
    </script>
    </body>
    

    views.py

    from django.shortcuts import render
    from django.http import HttpResponse, HttpResponseRedirect
    from fileup.models import *
    from django.core.files.storage import FileSystemStorage
    
    
    def insert(request):
        return render(request, 'index.html')
    
    
    def testing_data(request):
        if request.method == 'POST':
            dcn1 = request.POST['dcn']
            dc = request.POST['dc']
    
            upload_file = request.FILES['docf']
            fs = FileSystemStorage()
            fs.save(upload_file.name, upload_file)
    
    
            FileDB.objects.create(
                docname=dcn1,
                doc=dc,
            )
    
            return HttpResponse('')
    
    
    

    urls.py

    from django.contrib import admin
    from django.urls import path
    from fileup.views import *
    from django.conf.urls.static import static
    from django.conf import settings
    
    urlpatterns = [
        path('admin/', admin.site.urls),
        path('', insert),
        path('user', testing_data),
    ]
    if settings.DEBUG:
        urlpatterns += static(settings.STATIC_URL, document_root=settings.STATIC_ROOT)
        urlpatterns += static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT)
    
    

    settings.py config

    MEDIA_ROOT = os.path.join(BASE_DIR, 'media')
    MEDIA_URL = '/media/'
    
    

    Now, the media directory is being created upon file upload and files are being saved inside it.


  2. You are not doing it a right way, you should supply FormData in your Ajax call. see below:

    function upload(event) {
    event.preventDefault();
    var data = new FormData($('form').get(0));
    
    $.ajax({
        url: 'user/',
        type: 'POST,
        data: data,
        cache: false,
        processData: false,
        contentType: false,
        success: function(data) {
            alert('success');
        }
    });
    return false;
    }
    
    $(function() {
        $('form').submit(upload);
    });
    

    and in your view you should get the file from request.FILE like below:

    def testing_data(request):
        if request.method == 'POST':
            form = FileUploadForm(data=request.POST, files=request.FILES)
            if form.is_valid():
                print 'valid form'
            else:
                print 'invalid form'
                print form.errors
        return HttpResponseRedirect('/')
    
    Login or Signup to reply.
  3. You say everything works correctly except the storage location of the file.
    The following code will store uploaded files under /media/photos regardless of what your MEDIA_ROOT setting is:

    from django.core.files.storage import FileSystemStorage
    from django.db import models
    
    fs = FileSystemStorage(location='/media/photos')
    
    class Car(models.Model):
        ...
        photo = models.ImageField(storage=fs) 
    

    Hope this helps you. Courtesy of Django Doc: https://docs.djangoproject.com/en/3.1/topics/files/

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search