我有一个Django表单,用户可以在其中提交文本搜索字符串(下面是完整的示例设置)。
问题:当前由同一个URL模式所约束的同一视图处理的两个POST请求如何(也应该)通过第一个POST请求彼此“交谈”,从而将数据传递给第二个POST请求?
问题的症结在下面的块class MyModel(models.Model):
x1= models.CharField(max_length=100)
x2= models.CharField(max_length=255, blank=True)
x3= models.CharField(max_length=255, blank=True)
content_type = models.ForeignKey(ContentType, on_delete=models.CASCADE)
object_id = models.IntegerField()
content_object = GenericForeignKey()
def custom_models(object):
my_models= MyModel.objects.filter(object_id=OuterRef('pk'), content_type=ContentType.objects.get(model='mymodel', app_label='app_my_model'))
return MyModel.objects.filter(
object_id=object.pk,
content_type=ContentType.objects.get_for_model(object)
).annotate(related_my_models=Subquery(my_models))
中:我需要从第一个POST请求访问elif request.POST["router"] == "csv"
对象,但是基本的Python作用域/控制流程使我无法这样做。
当前,所有内容都生活在同一个URLconf results
中,并且基于(1)请求是否为GET / POST,(2)POST请求path
/ {{1} }属性来自其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})
答案 0 :(得分:0)
您可以想到一些选择:
返回结果并将其发送给第二个请求
您可能在视图中拥有第一个路径(处理router="run"
分支的路径)返回JSONResponse而不是HTTPResponse
对象,该对象生成或呈现具有已插入结果的表单<form>
元素。无论哪种方式,其想法都是将结果存储在前端,然后将其作为参数返回给另一个router="csv"
分支
存储到Django会话
您还可以利用Django会话,将字符串化的结果列表存储到request.session['results']
,然后在request.session['results']
分支中检查router="csv"
。然后,只需在CSV分支中检查request.session['results']
。