"Media" folder not being created with Django's FileSystemStorage. Files don't get saved if made manually either

479 Views Asked by At

So, I always test out new things in a separate project and the example that I used to test this out worked. However, trying to integrate the same in my project doesn't give me the results I need. I've spent close to 4 hours on this now and nothing so far.

First off, here's the code:

index.html

<form id="data" enctype="multipart/form-data">
<div class="col-md-4">
 <label class="file">
 <input type="file" id="file1" name="document" multiple>
 <span class="file-custom">Documents</span>
 <button type="button" onclick="enterdata()">Submit</button>
</div>
</form>
 
<script>
function enterdata(){
 if ($"data")[0].checkValidity(){
  alert('validity success');
  var token = ''{{ csrf_token }};
  alert('csrf generated');
  $.ajax({
     type:'POST',
     url:'/user',
     data: {
      doc1:$('file1').val()
   },
   header: {'X-CSRFToken': token},
   success: function(){
     alert("Added");
     $('#data').trigger("reset");
   }
  })
}else{
  $('data')[0].reportValidity()
  }
}
</script>

views.py

def testing_data(request):
 if request.method == 'POST':
 doc11 = request.POST['doc1']
 
 request_file = request.FILES['document'] if 'document' in request.FILES else None
        if request_file:
            # save attatched file
            # create a new instance of FileSystemStorage
            fs = FileSystemStorage()
            file = fs.save(request_file.name, request_file)
            # the fileurl variable now contains the url to the file. This can be used to serve the file when needed.
            fileurl = fs.url(file)
 landform.objects.create
 (
   mutdoc=doc11,
 )
return HttpResponse('')

models.py

class landform(models.Model):
 mutdoc = models.CharField(max_length=255)

urls.py

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

settings.py

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

So, the current code is taking the path and putting it in the mutdoc field in my model, this is alright and I have a lot of other fields that I have omitted from the above code. But apart from all that, the code that gets the file and saves it in the media directory is working fine when I run it independently in another project (without Ajax). But in my project when I combine it in that view above and Ajax, everything else works as expected apart from Django creating a media folder and putting the selected file inside it.

Crawled through tons of other SO threads and blog posts and videos but still can't get it to work.

Original

html


<form method = 'POST' class="col s12" enctype="multipart/form-data">

        {% csrf_token %}

        {{new_form.as_p}}

    <!--Below is our main file upload input -->
        <input type = "file" name = 'document'>
        <p><button type = "submit" class = "waves-effect waves-light btn">Publish</button></p>
</form>

views.py

from django.shortcuts import render
from django.core.files.storage import FileSystemStorage

def loadpage(request):
    if request.method == "POST":
        # if the post request has a file under the input name 'document', then save the file.
        request_file = request.FILES['document'] if 'document' in request.FILES else None
        if request_file:
            # save attatched file

            # create a new instance of FileSystemStorage
            fs = FileSystemStorage()
            file = fs.save(request_file.name, request_file)
            # the fileurl variable now contains the url to the file. This can be used to serve the file when needed.
            fileurl = fs.url(file)

    return render(request, "template.html")

urls.py

urlpatterns = [
    path('admin/', admin.site.urls),
    path('', loadpage)
]
# only in development
if settings.DEBUG:
    urlpatterns += static(settings.MEDIA_URL, document_root = settings.MEDIA_ROOT)
1

There are 1 best solutions below

1
On

1. replace:

urlpatterns = [
  path('user', testing_data),
 ]

with

urlpatterns = [
  path('user/', views.testing_data, name='testing_data'),
]

2. This cuold be the problem. Try this:

replace:

<input type="file" id="file1" name="document" multiple>

with:

<input type="file" id="file1" name="document" >

I could not find a doc about if having multipleinside of <input> will force you to use request.FILES.getlist('document') rather than request.FILES['document'] or not, but it is worth to try.