1

I would like to display a list of files from the MEDIA_ROOT on my server in a form in the frontend of a Django app.

Below what I am trying to accomplish:

enter image description here

My actual code below. I am showing only the classes, functions and files impacted by the issue. At the end of the question you will find a link to the full project if something is missing.

views.py (I have two functions because I tried both approaches)

class SelectPredFileView(TemplateView):
    """
    This view is used to select a file from the list of files in the server.
    """
    model = FileModel
    fields = ['file']
    template_name = 'select_file_predictions.html'
    success_url = '/predict_success/'
    files = os.listdir(settings.MEDIA_ROOT)

    def my_view(request):
        my_objects = get_list_or_404(FileModel, published=True)
        return my_objects

    # TODO: file list not displayed in the HTML, fix
    def getfilelist(self, request):
        filepath = settings.MEDIA_ROOT
        file_list = os.listdir(filepath)
        return render_to_response('templates/select_file_predictions.html', {'file_list': file_list})

settings.py

STATIC_URL = '/static/'
STATIC_ROOT = os.path.join(os.path.dirname(BASE_DIR), "static")

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

models.py

from django.db import models
from django.conf import settings


class FileModel(models.Model):
    file = models.FileField(null=True, blank=True)
    timestamp = models.DateTimeField(auto_now_add=True)
    path = models.FilePathField(path=settings.MEDIA_ROOT, default=settings.MEDIA_ROOT)

urls.py

from django.contrib import admin
from django.conf import settings
from django.urls import path, re_path
from django.views.static import serve
from django.conf.urls import url, include
from django.conf.urls.static import static

from App.views import UploadView, UploadSuccessView, IndexView, SelectPredFileView, PredictionsSuccessView

urlpatterns = [
    url(r'^admin/', admin.site.urls),
    url(r'^App/', include('App.urls'), name="App"),
    url('index/', IndexView.as_view(), name='index'),

    # Urls to upload the file and confirm the upload
    url('fileupload/', UploadView.as_view(), name='upload_file'),
    url('upload_success/', UploadSuccessView.as_view(), name='upload_success'),

    # Urls to select a file for the predictions
    url('fileselect/', SelectPredFileView.as_view(), name='file_select'),
    url('predict_success/', PredictionsSuccessView.as_view(), name='pred_success'),
]

urlpatterns += static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT)

if settings.DEBUG:

    import debug_toolbar
    urlpatterns = [
        path('__debug__/', include(debug_toolbar.urls)),
        re_path(r'^media/(?P<path>.*)$', serve, {'document_root': settings.MEDIA_ROOT, }),
    ] + urlpatterns

select_file_predictions.html

{% extends "index.html" %}

{% block content %}
    <form method="post" enctype="multipart/form-data">
        {% csrf_token %}
        {{ form.as_p }}
        {% for file in my_objects %}
          <input type="checkbox" name={ file } value="{ file }"><br>
        {% endfor %}
        <button type="submit" class="btn btn-primary">Upload file</button>
    </form>
{% endblock %}

ISSUE: the file are not shown in the html template.

enter image description here

If you want to dive deep, the full code of the application is here: https://github.com/marcogdepinto/Django-Emotion-Classification-Ravdess-API

Questions I checked without being able to solve this issue:

1) Iterate through a static image folder in django

2) Django - Render a List of File Names to Template

3) List directory file contents in a Django template

1 Answers1

4

I would do something like this:

views.py

from os import listdir
from os.path import isfile, join

import settings
from django.views.generic.base import TemplateView


class MyFilesView(TemplateView):

    template_name = "select_file_predictions.html"

    def get_context_data(self, **kwargs):
        context = super().get_context_data(**kwargs)        

        # List of files in your MEDIA_ROOT
        media_path = settings.MEDIA_ROOT
        myfiles = [f for f in listdir(media_path) if isfile(join(media_path, f))]
        context['myfiles'] = myfiles

        return context

select_file_predictions.html

{% extends "index.html" %}

{% block content %}
    <form method="post" enctype="multipart/form-data">
        {% csrf_token %}
        {{ form.as_p }}
        {% for myfile in myfiles %}
          <input type="checkbox" name={{ myfile }} value="{{ myfile }}"><br>
        {% endfor %}
        <button type="submit" class="btn btn-primary">Upload file</button>
    </form>
{% endblock %}
lorenzo
  • 627
  • 8
  • 12