Вопрос
У меня есть форма Django, в которой пользователь отправляет строку текстового поиска (полный пример настройки приведен ниже).
Вопрос: как можно (и нужно) два запроса POST, в настоящее времяобрабатывается одним и тем же представлением, привязанным к одному и тому же шаблону URL, «разговаривать» друг с другом через первый пост-запрос, передавая данные второму?
Суть проблемы в блоке 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>
In 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>
In 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})
In my_app/models.py
:
class MyModel(models.Model):
# Not important what this does for this example,
# just a placeholder.