django 如果有两个表单和一个提交按钮,如何使用前缀?

mzsu5hc0  于 2022-11-26  发布在  Go
关注(0)|答案(1)|浏览(112)

我试着用一个提交按钮上传两个表单。用户可以选择一个pdf文件和一个excel文件。然后上传两个文件。然后返回两个文件的内容。
所以我尝试用一个提交按钮上传两个文件。
但上传文件时,两个选定的文件选项不可见。
我有这样的模板:

{% 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 %}
                                {{ form.0.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">
                                {{ form.1.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 %}

和www.example.com上views.py:

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'):

                        wb = openpyxl.load_workbook(excel_file)
                        worksheet = wb['Sheet1']
                        print(worksheet)
                        excel_data = list()

                        for row in worksheet.iter_rows():
                            row_data = list()
                            for cell in row:
                                row_data.append(str(cell.value))
                                excel_data.append(row_data)
                                print(excel_data)
                                content_excel = excel_data

                        else:
                            content_excel = f.read()

                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,
        })

和forms.py:

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

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

urls.py:

urlpatterns = [  
    path('', views.starting_page, name='starting_page'),
    path('controlepunt140', views.ReadingFile.as_view(), name='controlepunt140'),    
]
whlutmcx

whlutmcx1#

模板中使用的变量名是字典的 key,而不是值。值是django渲染页面时 * 插入 * 到模板中的内容。
您的模板中有{{form1.as__p}},但是您发送"form": [form1, form2]作为上下文,因此模板中的变量应该是{{ form.0.as_p }}{{ form.1.as_p }}。我还没有测试过这个,但是如果它不起作用,您可以分别发送这两个表单,如下所示:

from django.shortcuts import redirect

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 redirect('main:controlepunt140')
                # 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,
        })

您可能还应该在表单提交并成功保存后更改为重定向。请查看Post/Redirect/Get和/或rendering content after a succesful post request

编辑

将模板更改为使用{{ form.0.as_p }},如@nigel239所示
您可以重定向到提交表单的同一页,这样,如果用户出于某种原因点击浏览器上的刷新按钮,您将不会收到一个警告框,要求用户重新发送表单。

相关问题