两个POST请求之间的通信

时间:2019-05-31 15:43:23

标签: python django django-forms

问题

我有一个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})

1 个答案:

答案 0 :(得分:0)

您可以想到一些选择:

返回结果并将其发送给第二个请求

您可能在视图中拥有第一个路径(处理router="run"分支的路径)返回JSONResponse而不是HTTPResponse对象,该对象生成或呈现具有已插入结果的表单<form>元素。无论哪种方式,其想法都是将结果存储在前端,然后将其作为参数返回给另一个router="csv"分支

存储到Django会话

您还可以利用Django会话,将字符串化的结果列表存储到request.session['results'],然后在request.session['results']分支中检查router="csv"。然后,只需在CSV分支中检查request.session['results']