为什么我无法使用 Django 下载我的文档?以及如何去做?

Why I'm unable to download my document with django? and how to do it?

我是 django 的新手,还在学习,我来到这里,在我自己的无限循环中,如果我按照我应该的方式去做,但我有一个错误,它不会工作,但如果我这样做像这样没有错误,但它不起作用。我希望用户能够按照他的意愿创建 excel 模板,这是我想要工作的简化版本,只需输入少量信息并在此基础上创建 excel 模板。

这是views.py

from django.http import HttpResponse
from django.shortcuts import render
import xlsxwriter
from xlsxwriter import workbook
from django.forms import Form, CharField, ChoiceField, IntegerField
from django.core.validators import MaxValueValidator, MinValueValidator

def home(request):
    return render(request, 'my_app/home.html')

class TemplateForm(Form):
    doc_name = CharField(label='Document name')
    sheetnames = CharField(label='Sheetnames')
    choices = []
    for year in range (1900, 2050):
        choices.append( (year, year) )
    year1 = ChoiceField(label='Starting Year', initial=2021, choices=choices)
    year2 = ChoiceField(label='Ending Year', initial=2022, choices=choices)    
    row_names = CharField(label='Column names')

def create_template(request):
    if request.method == 'GET':
        form = TemplateForm()
        return render(request, 'my_app/create_template.html', {'form':form})
    else:
        form = TemplateForm(request.POST)

def create_form(doc_name, sheetnames, years, row_names):
    workbook = xlsxwriter.Workbook(doc_name + '_template.xlsx')
    worksheet_introduction = workbook.add_worksheet( "introduction" )
    for i in sheetnames:
        worksheet_data = workbook.add_worksheet(i)
        worksheet_data.write_row(0, 1, years)
        worksheet_data.write_column(1, 0, row_names)
    workbook.close()
    return workbook

这是my_app/templates/my_app/create_template.html

{% extends "my_app/base.html" %}
{% block content %}

<form action="create_template" method="GET">
  {% csrf_token %}
  <h1>Create your template</h1>
  <div class="item">
    <table>
      {{ form.as_table }}
    </table>
  </div>
  <div class="btn-block">
    <input type="button" type="submit" value="Create and Download!"/>
  </div>
</form>
{% endblock content %}

这是my_app/urls.py

from django.urls import path
from . import views

urlpatterns = [
    path('', views.home, name='my-home'),
    path('create-template/', views.create_template, name='my-create-template'),
]

当你陷入困境时,最好的办法就是分解事物并一次解决一个问题。我简化了你的例子,这样你就可以有一些工作来扩展到你需要的东西。从 Django 开始。我创建了一个 urls.py,它有一个默认的回家路线。

from django.urls import path
from . import views

urlpatterns = [
    path('', views.home, name='my-home'),
]

这会调用 views.py 中的 home 函数。第一次访问页面时,使用 GET 方法初始化表单。当您单击提交时,它使用 POST 方法到同一页面 (action="", method="POST")。同一视图仅在这次不是 GET 时再次调用,因此它调用 create_workbook 函数以使用表单数据保存文件。保存后,它会让用户知道文件名,如果出现任何问题,它会重定向回表单页面。

views.py

from django.shortcuts import render, HttpResponse, redirect
import xlsxwriter
from django.forms import Form, CharField, ChoiceField


class TemplateForm(Form):
    doc_name = CharField(label='Document name')
    sheet_name = CharField(label='Sheetname')
    choices = []
    for year in range(1900, 2050):
        choices.append((year, year))
    year1 = ChoiceField(label='Starting Year', initial=2021, choices=choices)
    year2 = ChoiceField(label='Ending Year', initial=2022, choices=choices)


def home(request):
    if request.method == 'GET':
        form = TemplateForm()
        return render(request, 'my_app/create_template.html', {'form': form})
    else:
        form = TemplateForm(request.POST)
        if form.is_valid():
            create_workbook(form.cleaned_data.get('doc_name'), form.cleaned_data.get('sheet_name'), form.cleaned_data.get('year1'), form.cleaned_data.get('year2'))
            return HttpResponse(f"saved workbook to {form.cleaned_data.get('doc_name')}_template.xlsx")
        return redirect('my-home')


def create_workbook(doc_name, sheet_name, year1, year2):
    workbook = xlsxwriter.Workbook(doc_name + '_template.xlsx')
    worksheet = workbook.add_worksheet(sheet_name)
    row = 0
    col = 0
    year1 = int(year1)
    year2 = int(year2)
    if year1 <= year2:
        years = range(year1, year2)
    else:
        years = range(year2, year1)
    for i in years:
        worksheet.write(row, col, i)
        row += 1
    workbook.close()

my_app/base.html

<html>
<head>

</head>
<body>
    {% block content %}{% endblock %}
</body>
</html>

my_app/create_template.html

{% extends "my_app/base.html" %}
{% block content %}

<form action="" method="POST">
  {% csrf_token %}
  <h1>Create your template</h1>
  <div class="item">
    <table>
      {{ form.as_table }}
    </table>
  </div>
  <div class="btn-block">
    <input type="submit" value="Create and Download!"/>
  </div>
</form>
{% endblock content %}

希望这个工作示例会有所帮助。