Form not rendering for file upload input

I’m trying to build a dashboard where I upload a file, do some processing to the file and then using ML to make predictions and visualization on the file data. However, I’m getting an issue with my form where by when I use {{ form.as_p }} or {{ form.as_div }} or even {{ form }}, the input field for uploading the file just refuses to render on the web. It only appears when I click on the “Upload” button, I don’t know why it just doesn’t show up at the beginning, anyone available to help me figure it out? Here’s the code below. Thanks a lot in advance.

forms.py

from django import forms
from django.forms import ModelForm, Form
# from gui_app.models import SigFile

class SigFileForm(Form):
    file = forms.FileField(required = True, widget=forms.FileInput(attrs={'accept': '.csv'}))```


views.py
```py
from django.shortcuts import render, redirect
from django.http import HttpResponse, HttpResponseRedirect
from django.conf import settings
from django.core.files.storage import FileSystemStorage
from .forms import SigFileForm

def model_upload(request):
    # return render(request, 'model_upload.html')
    if request.method == 'POST':
        form = SigFileForm(request.POST, request.FILES)
        if form.is_valid():
            sigfile = request.FILES['sigfile']
            sigfile_name = sigfile.name
            sigfile_url = sigfile.url
            print(sigfile_name)
            print(sigfile_url)
            form.save()
            return redirect('model_upload')
        else:
            return render(request, 'model_upload.html', {'form': form})
    else:
        return render(request, 'model_upload.html')```


model_upload.html
```html
{% extends 'base.html' %}

{% block content %}
 
 <div class="form-container">
     <form id="form" method="post" enctype="multipart/form-data">
         {% csrf_token %}
     <!-- <label for="sigfile">Upload file: </label> -->
        {{ form }}
     <button type="submit", id = 'uploadSignalButton'>Upload</button>
     </form>
     <div class="dropdown">
         <label for="signalSelect">Select Signal: </label>
         <select name="signal-dropdown" id="signalSelect">
             {% for choice in choices %}
                 <option value="{{ choice.0 }}">{{ choice.1 }}</option>
             {% endfor %}
         </select>
     </div>
     
 </div>

 {% if myfile_url %}
   <p>File uploaded at: <a href="{{ myfile_url }}">{{ myfile_url }}</a></p>
 {% endif %}

{% endblock %}```

base.html
```{% load static %}
<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <link rel="stylesheet" href="{% static 'css/style.css' %}" type = "text/css">
    <!-- <script src="{% static 'js/index.js'}" type = "text/js" defer></script> -->
    <title>ERG Dashboard</title>
  </head>
  <body>

    {% block content %}
    {% endblock %}

  </body>
</html>```

The issue seems in your views.py file. If the request is not POST, you need to include the form in your context. So like this:

from django.shortcuts import render, redirect
from django.http import HttpResponse, HttpResponseRedirect
from django.conf import settings
from django.core.files.storage import FileSystemStorage
from .forms import SigFileForm

def model_upload(request):
    # return render(request, 'model_upload.html')
    if request.method == 'POST':
        form = SigFileForm(request.POST, request.FILES)
        if form.is_valid():
            sigfile = request.FILES['sigfile']
            sigfile_name = sigfile.name
            sigfile_url = sigfile.url
            print(sigfile_name)
            print(sigfile_url)
            form.save()
            return redirect('model_upload')
        else:
            return render(request, 'model_upload.html', {'form': form})
    else:
        form = SigFileForm()
        return render(request, 'model_upload.html', {'form': form)

When you click the upload, where you have not provided valid details, the form is not valid, so this line of code runs and sends the form to the client:

        else:
            return render(request, 'model_upload.html', {'form': form})
1 Like

Now it works, thanks a lot for the help. I appreciate it a lot.

I would just like to add a side note here for your future reference.

Thank you for using the ``` to fence your code, however, those lines of ``` must be lines by themselves and not be part of other lines. (That’s why you’ve got some instances of ``` actually showing in your post. If they’re lines of their own, you don’t see them.)

1 Like

Got it, no problem. I actually tried to separate them but had some difficulty with that so I just decided to leave it. I’m used to the discord style so this one was a bit confusing for me. Thanks for clarification anyway.