How to us the prefix if there are two forms and one submit button?

I try to upload two forms with one submit button. A user can select a pdf file and a excel file. And then uploading both files. And then the contents of both are returned.

So I try to upload both files with one submit button.

But the two selected file options are not visible for uploading the files.

So I have the template like this:

{% extends 'base.html' %} {% load static %} {% block content %}

<!DOCTYPE html>
<html lang="en">
    <head>
        <meta charset="UTF-8" />
        <meta name="viewport" content="width=device-width, initial-scale=1.0" />
        <title>Create a Profile</title>
        <script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
        <link rel="stylesheet" type="text/css" href="{% static 'main/css/custom-style.css' %}" />
        <link rel="stylesheet" type="text/css" href="{% static 'main/css/bootstrap.css' %}" />
    </head>
    <body>
        <div class="container center">
            <span class="form-inline" role="form">
                <div class="inline-div">
                    <form class="form-inline" action="/controlepunt140" method="POST" enctype="multipart/form-data">

                        <div class="d-grid gap-3">
                            <div class="form-group">
                                {% csrf_token %}
                                {{form1.as__p}}
                                <button type="submit" name="form_pdf" class="btn btn-warning">Upload!</button>
                            </div>
                            <div class="form-outline">
                                <div class="form-group">
                                    <textarea class="inline-txtarea form-control" id="content" cols="70" rows="25">
                                    {{content}}</textarea>
                                </div>
                            </div>
                        </div>

                        <div class="d-grid gap-3">
                            <div class="form-group">
                                {{form2.as__p}}
                            </div>
                            <div class="form-outline">
                                <div class="form-group">
                                    <textarea class="inline-txtarea form-control" id="content" cols="70" rows="25">
                                    {{conten_excel}}</textarea>
                                </div>
                            </div>
                        </div>
                    </form>
                </div>
            </span>
        </div>  
    </body>
</html>
{% endblock content %}

and the views.py:

class ReadingFile(View):
    def get(self, *args, **kwargs):
        form = [UploadFileForm(), ExcelForm()]
        return render(self.request, "main/controle_punt140.html", {
            "form": form
        })

    def post(self, *args, **kwargs):
        filter_text = FilterText()
        types_of_encoding = ["utf8", "cp1252"]
        form1 = UploadFileForm(self.request.POST, self.request.FILES, prefix="form1")
        form2 = ExcelForm(self.request.FILES, self.request.FILES, prefix="form2")
        content = ''
        content_excel = ''

        if form1.is_valid() and form2.is_valid() and self.request.POST:
            uploadfile = UploadFile(image=self.request.FILES["upload_file"])
            excel_file = self.request.FILES["upload_file"]

            uploadfile.save()

            for encoding_type in types_of_encoding:
                with open(os.path.join(settings.MEDIA_ROOT, f"{uploadfile.image}"), 'r', encoding=encoding_type) as f:
                    if uploadfile.image.path.endswith('.pdf'):
                        content = filter_text.show_extracted_data_from_file(
                            uploadfile.image.path)
                    else:
                        content = f.read()

                    if uploadfile.image.path.endswith('xlsx'):
                        
                        #Uploading excel form:
                        #this is just logic. 
                         pass

                        else:
                            content_excel = f.read()

                return render(self.request, "main/controle_punt140.html", {
                    'form': [ExcelForm(), UploadFileForm()],
                    "content": [content, content_excel]
                })

            return render(self.request, "main/controle_punt140.html", {
                "form": [form1, form2]
            })

and forms.py:

class UploadFileForm(forms.Form):
    upload_file = forms.FileField(required=False)


class ExcelForm(forms.Form):
    upload_file = forms.FileField(required=False)

The variable name used in the template is the key of the dictionary, not the value. The value is what is inserted into the template when django renders the page.

You have {{form1.as__p}} in your template, but you send "form": [form1, form2] as your context, so the variable in the template should be {{ form[0].as_p }} and {{ form[1].as_p }}. I haven't tested this, but if it doesn't work, you could just send the two forms separately like:

class ReadingFile(View):
    def get(self, *args, **kwargs):
        return render(self.request, "main/controle_punt140.html", {
            "form1": UploadFileForm(),
            "form2": ExcelForm()
        })

    def post(self, *args, **kwargs):
        filter_text = FilterText()
        types_of_encoding = ["utf8", "cp1252"]
        form1 = UploadFileForm(self.request.POST, self.request.FILES, prefix="form1")
        form2 = ExcelForm(self.request.FILES, self.request.FILES, prefix="form2")
        content = ''
        content_excel = ''

        if form1.is_valid() and form2.is_valid() and self.request.POST:
            uploadfile = UploadFile(image=self.request.FILES["upload_file"])
            excel_file = self.request.FILES["upload_file"]

            uploadfile.save()

            for encoding_type in types_of_encoding:
                with open(os.path.join(settings.MEDIA_ROOT, f"{uploadfile.image}"), 'r', encoding=encoding_type) as f:
                    if uploadfile.image.path.endswith('.pdf'):
                        content = filter_text.show_extracted_data_from_file(
                            uploadfile.image.path)
                    else:
                        content = f.read()

                    if uploadfile.image.path.endswith('xlsx'):
                        
                        #Uploading excel form:
                        #this is just logic. 
                         pass

                        else:
                            content_excel = f.read()
                
                # You probably should do a redirect after the form is
                # submitted, rather than render the page.
                return render(self.request, "main/controle_punt140.html", {
                    'form1': ExcelForm(), 
                    'form2': UploadFileForm(),
                    "content": [content, content_excel]
                })
        
        # I've adjusted the indent here to what I think it should be.
        return render(self.request, "main/controle_punt140.html", {
            "form1": form1, 
            "form2": form2,
        })

You probable should also change to a redirect after the form is submitted and saved successfully. Check out Post/Redirect/Get and/or rendering content after a succesful post request.

Back to Top