【问题标题】:Django: Pass form.cleaned_data to the view that handles the page to where user is being redirected with HttpResponseRedirectDjango:将 form.cleaned_data 传递给处理页面的视图,该页面使用 HttpResponseRedirect 重定向用户
【发布时间】:2021-06-08 21:30:58
【问题描述】:

更新:2021-06-09:在下面添加了代码示例 更新:2021-06-10:反馈后编辑代码

我有以下情况,非常感谢您的帮助。

利用 Post/Redirect/Get 设计模式,我使用 Django Forms 创建了一个表单。 然后这会重定向到带有 HttpResponseRedirect 的页面。我已经为该页面创建了一个视图,并且该部分工作正常。

我想使用重定向页面上的表单数据 (form.cleaned_data) 将 (form.cleaned_data) 值动态插入到 sql 脚本并使用模板显示结果。

一切顺利,但我只是没有成功传递表单数据。

什么有效:

  • 表单(以及带有该表单的视图)。
  • Sql 功能有效,没有动态添加表单数据,所以现在是静态 sql。
  • 模板工作正常
  • 重定向工作正常。

如您所见,一切正常,但我无法使其动态化。

如何捕获清理后的表单数据并将其传递/转发到使用 HttpResponseRedirect 加载的页面(视图)(即使用 GET 方法加载的页面)?

非常感谢您。

views.py

    class TestView(FormView):
    template_name = 'app_testing/testform.html'
    form_class = TestForm
    # success_url = '/app_testing/testformresult.html'

    def form_valid(self, form):
        cl_ref_num = form.cleaned_data['cl_ref_num']
        test = 'test'
        print(f'cl ref num in form validation in class TestView = {cl_ref_num}')
        print(f'test in form validation in class TestView = {test}')
        return redirect(reverse('testformresult'), cl_ref_num=cl_ref_num, test=test)

class TestResultView(TemplateView):
    template_name = 'app_testing/testformresult.html'

    def get_context_data(self, *args, **kwargs):
        ctx = super(TestResultView, self).get_context_data(**kwargs)
        cl_ref_num = kwargs.get('cl_ref_num')
        test = kwargs.get('test')
        print(f'cl ref num after redirect in class TestResultView = {cl_ref_num}')
        print(f'test after redirect in class TestResultView = {test}')
        return ctx

使用动态值 {xx} 在重定向页面上运行的 sql 查询应在从 SearchTransaction 重定向到 SearchTransactionResult 时传递

def test_payment(xx):
        query = f"""select *
    from table p
    where 1=1
    and p.something = '{xx}'
    """
        with connections['testing'].cursor() as cursor:
            cursor.execute(query)
            headers = [row[0] for row in cursor.description]
            data = cursor.fetchall()
        return headers, data

最诚挚的问候, 皮松

【问题讨论】:

  • 好吧,您没有附加任何特定代码(看不到实际用途),但您可以通过多种方式执行此操作 - 会话、消息或特殊视图。提供更多详细信息或代码以获得更多帮助
  • 一般不会。您可以使用 redirect("yourapp:yourget_urlpath_name" yourobject.slug 之类的东西或类似的东西,然后视图会查找对象并相应地显示。
  • 亲爱的,我添加了一些代码来澄清问题。感谢您迄今为止所做的贡献。同时,我会查找是否可以通过会话解决此问题,但我仍然会感谢您的解决方案。 @quqa123 你说的“信息或特殊观点”是什么意思?

标签: python python-3.x django django-views django-forms


【解决方案1】:

就我所见,您正在朝着正确的方向前进,但必须习惯 Django。几年前,我遇到了完全相同的问题,我明白这不是做事的最佳方式。我将尝试根据您的示例代码介绍您将如何做这样的事情的标准方式

class SearchTransaction(FormView):

    template_name = 'app_search/search-transaction.html'
    from_class = ClRefNumForm

    """
    this is not needed anymore FormView handles this code for you
    def get(self, request):
        # rendering some form that finds some Transaction in Database
        return render(request, "app_search/search-transaction.html", {
            "form": form})
    """

    def form_valid(self, form):
        # you find the transaction with a use of your form
        transaction = somehow_get_transaction_from_form(form.cleaned_data)
        return redirect(reverse('transaction-detail', args=(transaction.pk,)))
    
    """
    if form is invalid FromView will do what you also did in your code
    """

class SearchTransactionResult(DetailView):
    
    model = Transaction
    
    """
    you can access the Transaction model from the view
    its added to context as {{ object }} or in your business logic
    as self.object
    """

在你的urls.py

urlpatterns = [
    ...
    path('search-transaction-result/<int:pk>/', 
      SearchTransactionResult.as_view(), name='transaction-detail')),
    ....
]

除了请求-响应处理之外,您一直在做的事情并没有使用任何实际的 Django 框架。 这是关于FromView 的文档 这里是DetailView

如果那不是您想要做的事情,请发表评论并弄清楚。我知道至少有 5 种方法可以做(我认为)你想要达到的目标,但这个是最清楚的。
如果您想将小参数传递给某个视图并且不太关心安全性或以某种方式处理它,您可以使用 url 参数

xx = get_xx_from_form_somehow(form)  # has to be url-encoded
return HttpResponseRedirect("search-transaction-result?xx="+xx)

class SearchTransactionResult(View):
    def get(self, request):
        xx = request.GET.get('xx')
        # now you passed variable from one view to another

如果你真的需要传递变量

只需将其添加到 url(如果它是敏感数据,我强烈建议使用 HTTPS)

class SearchTransaction(FormView):
    template_name = 'app_search/search-transaction.html'
    from_class = ClRefNumForm

    def form_valid(self, form):
        # you find the transaction with a use of your form
        transaction_id = form.cleaned_data['transaction_id']
        return redirect(reverse('transaction-detail', transaction_id=transaction_id))


class SearchTransactionResult(TemplateView):

    template_name = 'app_search/search-transaction-result.html'

    def get_context_data(self, **kwargs):
        ctx = super(SearchTransactionResult, self).get_context_data(**kwargs)
        transaction_id = kwargs.get('transaction_id')
        transaction = your_sql_transaction_obtain()
        ctx['transaction'] = transaction
        # now u can access transaction as {{ transaction }} in your template
        return ctx

并在您的 urls.py 中添加带有变量的路径

    path('some-url/<str:transaction_id>/', SearchTransactionResult.as_view(), name='transaction-detail'),

【讨论】:

  • 非常感谢您的全面回答,如果我是对的,您的解决方案需要一个模型。我故意远离模型,因为我不使用数据库来存储信息。我只连接到 Oracle 数据库并从中提取数据。这就是为什么我想在不使用模型的情况下在视图之间传递数据(反正我还没有学过)。不过,我确实更改为 FormView,谢谢。你介意解释一下我如何在不使用模型但在任何情况下使用重定向的情况下在视图之间传递参数吗?
  • 是的,我将编辑答案,或者可能在最后添加无模型解决方案,但待定。使用没有模型的 ORM 框架就像拥有一辆汽车并自己推动它一样毫无意义,因为您没有时间加油。 Django 当然支持外部数据库 - 它非常流行。您可以阅读文档 herehere 如果您想要一个真正的生产应用程序,请考虑在意外发生之前花更多时间来发展您的 django 技能和知识。
  • @PieThon 我会在我的回答中重新塑造你的观点。如果您觉得不合适,请发表评论
  • @PieThon 你能分享一个你想从一个视图传递到另一个视图的数据示例吗,这对我回答你的问题很有帮助
  • 你好,当然。我有一种接受 transaction_id 的表格。该交易 ID 只是一个数字。用户必须使用表单提供此交易 ID。然后将验证表单,如果有效,它将重定向到“SearchTransactionResult”页面。在那个页面上,我连接了 sql 查询,该查询包装在一个需要参数的函数中。该参数应该是用户的输入,并将在 sql 查询中使用以关注该特定事务。类似“select * From db where transaction_id = {userinput}”
猜你喜欢
  • 2020-06-27
  • 2011-12-25
  • 2010-10-13
  • 2017-05-29
  • 2018-01-05
  • 2021-02-24
  • 1970-01-01
  • 1970-01-01
  • 2011-09-08
相关资源
最近更新 更多