python - 两个 POST 请求之间的通信
问题描述
问题
我有一个 Django 表单,用户在其中提交文本搜索字符串(下面的完整示例设置)。
问题:如何(并且应该)两个 POST 请求,当前由绑定到相同 URL 模式的相同视图处理,通过第一个 POST 请求将数据传递给第二个请求相互“交谈”?
问题的症结在下面的块elif request.POST["router"] == "csv"
中:我需要results
从第一个 POST 请求中访问对象,但是基本的 Python 范围/控制流阻止了我这样做。
目前,所有内容都位于同一个 URLconf 中path
,并且基于 (1) 请求是否为 GET/POST,(2) POST 请求name
/value
属性来自其<input>
标签的内容而不同地处理。
设置
进口:
import csv
from time import time_ns
from django import forms
from django import models
from django.http import HttpResponse
from django.shortcuts import render, get_object_or_404
from django.urls import path
在my_app/urls.py
:
urlpatterns = [
path("run/<uuid:pk>", views.run),
]
在my_app/forms.py
:
class RunForm(forms.Form):
start = forms.DateTimeField()
query = forms.CharField()
在my_app/templates/my_app/run.html
:
<form method="post">
{% csrf_token %}
<h1>Launch a search</h1>
<table>
{{ form.as_table }}
</table>
<input type="hidden" name="router" value="run">
<input type="submit" value="Submit">
</form>
在my_app/templates/my_app/results.html
:
<table>
{% for row in results %}
<tr>
{% for val in row %}
<td>{{ val }}</td>
{% endfor %}
</tr>
{% endfor %}
</table>
<form method="post">
{% csrf_token %}
<input type="hidden" name="router" value="csv">
<input type="submit" value="Download to CSV">
</form>
在my_app/views.py
:
def run(request, pk):
if request.method == "POST":
if request.POST["router"] == "run":
form = RunForm(request.POST)
if form.is_valid():
obj = get_object_or_404(MyModel, pk=pk)
# Get some dynamic results from database based
# on `obj` and the form fields.
# The Python output is a lists of lists
# that should be rendered to a downloadable HTML <table>
results = [
[1, 2, 3],
[4, 5, 6],
]
return render(request, "my_app/results.html", {"results": results})
elif request.POST["router"] == "csv":
response = HttpResponse(content_type="text/csv")
response["Content-Disposition"] = f"attachment; filename=results-{time_ns():d}.csv"
writer = csv.writer(response)
# Ah! Now I need to access `results` from above. Do I inject
# `results` into another <form> on my_app/results.html?
# i.e.:
# for row in results:
# writer.writerow(row)
return response
else:
form = RunForm()
return render(request, "my_app/run.html", {"form": form})
在my_app/models.py
:
class MyModel(models.Model):
# Not important what this does for this example,
# just a placeholder.
解决方案
你有几个我能想到的选择:
返回结果并与第二个请求一起发回
您可以让视图中的第一个路径(处理router="run"
分支的路径)返回 JSONResponse 而不是HTTPResponse
生成或呈现表单的对象,结果已经插入到<form>
元素中。无论哪种方式,想法是将结果存储在前端,并将它们作为参数返回到另一个router="csv"
分支
存储到 Django 会话
您还可以利用 Django 会话,将字符串化结果列表存储到分支中request.session['results']
,然后request.session['results']
在router="csv"
分支中进行检查。然后只需检查request.session['results']
CSV 分支。
推荐阅读
- web - 如何将 Alexa 与 Web 应用程序集成?
- node.js - 如何知道条带json数据中的订阅开始日期和月份结束日期?
- bash - 在 Bash 中使用 mv comman 重命名存储在变量中的多个文件
- git - 如何在git中删除整个分支文件夹
- c# - Xamarin.Forms - 使用 XAML 元素作为参数
- php - symfony - Prestashop 1.7 - 我无法访问后台(管理面板)
- python - Oracle MERGE 重写为 PySpark。如果为空 - 更新,否则 - 插入
- php - 将关联数组插入数据库
- node.js - 观察/监听 REST API 响应的变化
- java - RefreshEndpoint Bean 不适用于 Spring Boot 2.4.2 和 Spring Cloud 2020.0.1