从表单导出数据
Export data from a form
我需要用户输入一些日期,以便使用这些日期查询数据库,所以我按照 步骤进行操作,现在可以正常工作了。我想要的是,除了显示响应中的数据之外,还能够将该数据导出到文件中。为此,我制作了一个表格,但我不知道如何继续。
我的问题是,我在哪里可以查阅有关如何从表单导出的文档?
观看次数
from django.shortcuts import render
from .forms import ContactForm
def filter_contracts(request):
form = ContractForm(request.POST or None)
contracts = None
if request.method == 'POST':
if form.is_valid():
contracts = Contract.objects.filter(person__is_doctor=False,
type_contract=Contract.FC,
starting_date__gte=form.cleaned_data.get('starting_date'),
ending_date__lte=form.cleaned_data.get('ending_date'))
return render(request, 'your_template.html', {'form': form,
'contracts': contracts})
表格
class ContractForm(forms.Form):
starting_date = forms.DateField()
ending_date = forms.DateField()
模板
{% extends "admin/base_site.html" %}
{% load i18n admin_urls admin_static admin_modify %}
{% block content %}
<form action="." enctype="db_personal/x-www-form-urlencoded" method="POST">>
<ul>
{{ form.as_ul }}
</ul>
{% csrf_token %}
<button type="submit">Search</button>
<br>
<hr>
{% if contracts %}
<table border ="1" cellspacing="0">
<th>Person</th>
<th>Contract type</th>
<th>Starting date</th>
<th>Ending date</th>
{% for contract in contracts %}
<tr>
<td>{{ contract.person }}</td>
<td>{{ contract.type_contract }}</td>
<td>{{ contract.starting_date }}</td>
<td>{{ contract.ending_date }}</td>
</tr>
{% endfor %}
</table>
{% endif %}
</form>
{% endblock %}
如果您想 return 您的查询集结果不是 HTML,只需让您的视图 return 数据采用您选择的适当格式——这可能是csv、xml、json、yaml 或纯文本。
有关如何导出 csv 数据的 Django 文档中的示例:
Django 文档也有一个如何导出 PDF 的页面:
在您看来——在您处理表单并查询数据库之后——您应该设置响应的内容类型,以便浏览器知道它期望的数据类型。您的格式化数据将进入响应正文。大多数浏览器只能显示 HTML 或纯文本,也许还有 XML,但它们只会将其他任何内容作为文件下载到用户的计算机上。
处理 "Download" 按钮的示例代码
步骤 1
在您的 forms.py
中,添加一个额外的表单来处理 "download" 按钮:
from django import forms
class ContractForm(forms.Form):
starting_date = forms.DateField()
ending_date = forms.DateField()
class DownloadForm(forms.Form):
starting_date = forms.CharField(widget=forms.HiddenInput)
ending_date = forms.CharField(widget=forms.HiddenInput)
此表单包含 2 个隐藏字段 -- starting_date
和 ending_date
。我们将根据初始搜索查询参数填充这些字段。
步骤 2
在您的 views.py
中,添加代码以呈现 DownloadForm
(作为按钮):
from django.shortcuts import render
from .forms import ContractForm, DownloadForm
def filter_contracts(request):
form = ContractForm(request.POST or None)
contracts = None
download_form = None
if request.method == 'POST':
if form.is_valid():
starting_date = form.cleaned_data.get('starting_date')
ending_date = form.cleaned_data.get('ending_date')
contracts = Contract.objects.filter(person__is_doctor=False,
type_contract=Contract.FC,
starting_date__gte=starting_date,
ending_date__lte=ending_date)
# Create the DownloadForm instance here so you can pass it in the
# context dict.
download_form = DownloadForm(initial={
'starting_date': starting_date,
'ending_date': ending_date
})
return render(request, 'your_template.html',
{
'form': form,
'contracts': contracts,
'download_form': download_form
})
实例化 DownloadForm
时,视图将 starting_date
和 ending_date
作为表单的初始参数,因此当模板呈现它时,它将在隐藏字段。 (您可以使用浏览器来确认这一点。)
步骤 3
现在,修改您的模板以添加 Download
按钮表单(这是您在上述步骤中添加到视图的 DownloadForm
实例):
{% extends "admin/base_site.html" %}
{% load i18n admin_urls admin_static admin_modify %}
{% block content %}
<form action="." enctype="db_personal/x-www-form-urlencoded" method="POST">
<ul>
{{ form.as_ul }}
</ul>
{% csrf_token %}
<button type="submit">Search</button>
<br>
<hr>
{% if contracts %}
<table border ="1" cellspacing="0">
<th>Person</th>
<th>Contract type</th>
<th>Starting date</th>
<th>Ending date</th>
{% for contract in contracts %}
<tr>
<td>{{ contract.person }}</td>
<td>{{ contract.type_contract }}</td>
<td>{{ contract.starting_date }}</td>
<td>{{ contract.ending_date }}</td>
</tr>
{% endfor %}
</table>
{% endif %}
</form>
{% if download_form %}
<form action="{% url 'download_data' %}" method="POST">
{% csrf_token %}
{{ download_form.as_p }}
<p>
<input type="submit" class="btn" name="submit" value="Download" />
</p>
</form>
{% endif %}
{% endblock %}
请注意,下载按钮的表单 action
使用名为 download_data
的命名 url。您必须向 urls.py
添加一个新的 url 规则来处理下载表单提交(请参阅下一步)。
步骤 4
向您的 urls.py
添加一个新规则来处理下载表单提交。这将映射到我们将创建的新视图,以 return CSV 格式的请求数据:
from django.conf.urls import patterns, url
from .views import filter_contracts, download_data
urls = patterns(
# url prefix
'',
# view to render search form
url(r'^contracts/$', filter_contracts, name='search_contracts'),
# view to handle data download
url(r'^contracts/download/$', download_data, name='download_data')
)
您必须根据您已经设置的内容调整 url 配置规则。以上只是一个指南和例子。
步骤 5
现在,在您的 views.py
中添加几个新视图来处理下载按钮提交和数据获取:
def get_csv_data(starting_date, ending_date):
"""
Prepare data in csv format for download.
* This is called by ``download_data`` to perform the query.
* Do your query here and format the results as CSV using a csv
writer or manually.
* For this example, we're using some dummy data.
"""
data = []
num = 10
for n in xrange(num):
person = 'Person {}'.format(n + 1)
type_contract = 'Some contract'
start_date = starting_date
end_date = ending_date
data.append(', '.join([start_date, end_date, person, type_contract]))
return '\n'.join(data)
def download_data(request):
"""
Process a request to download data.
* POST must contain 'starting_date' and 'ending_date'.
"""
from django.http import HttpResponse
try:
assert request.method == 'POST'
form = DownloadForm(request.POST)
assert form.is_valid()
starting_date = form.cleaned_data.get('starting_date')
ending_date = form.cleaned_data.get('ending_date')
assert starting_date and ending_date
contracts = get_csv_data(starting_date, ending_date)
assert contracts
except AssertionError:
error = 'Your request has some problems.'
contracts = error
attachment = 'contract_data.csv'
response = HttpResponse(content_type='text/csv')
response['Content-Disposition'] = 'attachment;filename="{}"'.format(attachment)
response.write(contracts)
return response
上面的get_csv_data
函数只是一个例子,准备一些虚拟数据用于测试。您应该将数据库查询代码放在那里以获取所需的查询集,然后将数据格式化为 CSV。 (示例函数手动格式化虚拟数据,但您应该使用 csv
模块来准备您的数据——请参阅本答案开头的 Django 示例以获取 link)。
总结
基本思路是:
- 当您呈现来自查询的合同搜索结果时,您只需向页面添加一个额外的
DownloadForm
实例。这仅显示为 Download
按钮,但它包含 starting_date
和 ending_date
的隐藏字段。
- 当用户点击
Download
按钮时,表单被提交到一个名为 download_data
的新视图,该视图检查 request.POST
字典并提取 starting_date
和ending_date
。然后,它准备查询集数据并以 CSV 格式呈现它。
download_data
将响应 return 视为内容类型为 text/csv
的附件。用户的浏览器会自动将其作为下载文件处理。
代码中的错误和安全检查很少,但这应该可以帮助您入门。
我需要用户输入一些日期,以便使用这些日期查询数据库,所以我按照
我的问题是,我在哪里可以查阅有关如何从表单导出的文档?
观看次数
from django.shortcuts import render
from .forms import ContactForm
def filter_contracts(request):
form = ContractForm(request.POST or None)
contracts = None
if request.method == 'POST':
if form.is_valid():
contracts = Contract.objects.filter(person__is_doctor=False,
type_contract=Contract.FC,
starting_date__gte=form.cleaned_data.get('starting_date'),
ending_date__lte=form.cleaned_data.get('ending_date'))
return render(request, 'your_template.html', {'form': form,
'contracts': contracts})
表格
class ContractForm(forms.Form):
starting_date = forms.DateField()
ending_date = forms.DateField()
模板
{% extends "admin/base_site.html" %}
{% load i18n admin_urls admin_static admin_modify %}
{% block content %}
<form action="." enctype="db_personal/x-www-form-urlencoded" method="POST">>
<ul>
{{ form.as_ul }}
</ul>
{% csrf_token %}
<button type="submit">Search</button>
<br>
<hr>
{% if contracts %}
<table border ="1" cellspacing="0">
<th>Person</th>
<th>Contract type</th>
<th>Starting date</th>
<th>Ending date</th>
{% for contract in contracts %}
<tr>
<td>{{ contract.person }}</td>
<td>{{ contract.type_contract }}</td>
<td>{{ contract.starting_date }}</td>
<td>{{ contract.ending_date }}</td>
</tr>
{% endfor %}
</table>
{% endif %}
</form>
{% endblock %}
如果您想 return 您的查询集结果不是 HTML,只需让您的视图 return 数据采用您选择的适当格式——这可能是csv、xml、json、yaml 或纯文本。
有关如何导出 csv 数据的 Django 文档中的示例:
Django 文档也有一个如何导出 PDF 的页面:
在您看来——在您处理表单并查询数据库之后——您应该设置响应的内容类型,以便浏览器知道它期望的数据类型。您的格式化数据将进入响应正文。大多数浏览器只能显示 HTML 或纯文本,也许还有 XML,但它们只会将其他任何内容作为文件下载到用户的计算机上。
处理 "Download" 按钮的示例代码
步骤 1
在您的 forms.py
中,添加一个额外的表单来处理 "download" 按钮:
from django import forms
class ContractForm(forms.Form):
starting_date = forms.DateField()
ending_date = forms.DateField()
class DownloadForm(forms.Form):
starting_date = forms.CharField(widget=forms.HiddenInput)
ending_date = forms.CharField(widget=forms.HiddenInput)
此表单包含 2 个隐藏字段 -- starting_date
和 ending_date
。我们将根据初始搜索查询参数填充这些字段。
步骤 2
在您的 views.py
中,添加代码以呈现 DownloadForm
(作为按钮):
from django.shortcuts import render
from .forms import ContractForm, DownloadForm
def filter_contracts(request):
form = ContractForm(request.POST or None)
contracts = None
download_form = None
if request.method == 'POST':
if form.is_valid():
starting_date = form.cleaned_data.get('starting_date')
ending_date = form.cleaned_data.get('ending_date')
contracts = Contract.objects.filter(person__is_doctor=False,
type_contract=Contract.FC,
starting_date__gte=starting_date,
ending_date__lte=ending_date)
# Create the DownloadForm instance here so you can pass it in the
# context dict.
download_form = DownloadForm(initial={
'starting_date': starting_date,
'ending_date': ending_date
})
return render(request, 'your_template.html',
{
'form': form,
'contracts': contracts,
'download_form': download_form
})
实例化 DownloadForm
时,视图将 starting_date
和 ending_date
作为表单的初始参数,因此当模板呈现它时,它将在隐藏字段。 (您可以使用浏览器来确认这一点。)
步骤 3
现在,修改您的模板以添加 Download
按钮表单(这是您在上述步骤中添加到视图的 DownloadForm
实例):
{% extends "admin/base_site.html" %}
{% load i18n admin_urls admin_static admin_modify %}
{% block content %}
<form action="." enctype="db_personal/x-www-form-urlencoded" method="POST">
<ul>
{{ form.as_ul }}
</ul>
{% csrf_token %}
<button type="submit">Search</button>
<br>
<hr>
{% if contracts %}
<table border ="1" cellspacing="0">
<th>Person</th>
<th>Contract type</th>
<th>Starting date</th>
<th>Ending date</th>
{% for contract in contracts %}
<tr>
<td>{{ contract.person }}</td>
<td>{{ contract.type_contract }}</td>
<td>{{ contract.starting_date }}</td>
<td>{{ contract.ending_date }}</td>
</tr>
{% endfor %}
</table>
{% endif %}
</form>
{% if download_form %}
<form action="{% url 'download_data' %}" method="POST">
{% csrf_token %}
{{ download_form.as_p }}
<p>
<input type="submit" class="btn" name="submit" value="Download" />
</p>
</form>
{% endif %}
{% endblock %}
请注意,下载按钮的表单 action
使用名为 download_data
的命名 url。您必须向 urls.py
添加一个新的 url 规则来处理下载表单提交(请参阅下一步)。
步骤 4
向您的 urls.py
添加一个新规则来处理下载表单提交。这将映射到我们将创建的新视图,以 return CSV 格式的请求数据:
from django.conf.urls import patterns, url
from .views import filter_contracts, download_data
urls = patterns(
# url prefix
'',
# view to render search form
url(r'^contracts/$', filter_contracts, name='search_contracts'),
# view to handle data download
url(r'^contracts/download/$', download_data, name='download_data')
)
您必须根据您已经设置的内容调整 url 配置规则。以上只是一个指南和例子。
步骤 5
现在,在您的 views.py
中添加几个新视图来处理下载按钮提交和数据获取:
def get_csv_data(starting_date, ending_date):
"""
Prepare data in csv format for download.
* This is called by ``download_data`` to perform the query.
* Do your query here and format the results as CSV using a csv
writer or manually.
* For this example, we're using some dummy data.
"""
data = []
num = 10
for n in xrange(num):
person = 'Person {}'.format(n + 1)
type_contract = 'Some contract'
start_date = starting_date
end_date = ending_date
data.append(', '.join([start_date, end_date, person, type_contract]))
return '\n'.join(data)
def download_data(request):
"""
Process a request to download data.
* POST must contain 'starting_date' and 'ending_date'.
"""
from django.http import HttpResponse
try:
assert request.method == 'POST'
form = DownloadForm(request.POST)
assert form.is_valid()
starting_date = form.cleaned_data.get('starting_date')
ending_date = form.cleaned_data.get('ending_date')
assert starting_date and ending_date
contracts = get_csv_data(starting_date, ending_date)
assert contracts
except AssertionError:
error = 'Your request has some problems.'
contracts = error
attachment = 'contract_data.csv'
response = HttpResponse(content_type='text/csv')
response['Content-Disposition'] = 'attachment;filename="{}"'.format(attachment)
response.write(contracts)
return response
上面的get_csv_data
函数只是一个例子,准备一些虚拟数据用于测试。您应该将数据库查询代码放在那里以获取所需的查询集,然后将数据格式化为 CSV。 (示例函数手动格式化虚拟数据,但您应该使用 csv
模块来准备您的数据——请参阅本答案开头的 Django 示例以获取 link)。
总结
基本思路是:
- 当您呈现来自查询的合同搜索结果时,您只需向页面添加一个额外的
DownloadForm
实例。这仅显示为Download
按钮,但它包含starting_date
和ending_date
的隐藏字段。 - 当用户点击
Download
按钮时,表单被提交到一个名为download_data
的新视图,该视图检查request.POST
字典并提取starting_date
和ending_date
。然后,它准备查询集数据并以 CSV 格式呈现它。 download_data
将响应 return 视为内容类型为text/csv
的附件。用户的浏览器会自动将其作为下载文件处理。
代码中的错误和安全检查很少,但这应该可以帮助您入门。