【问题标题】:Where is form data handled?? (Django)表单数据在哪里处理? (姜戈)
【发布时间】:2014-02-02 13:41:15
【问题描述】:

我已经阅读了很多关于在 Django 中创建和处理表单的 tuts 和文档,但我仍然对实现的某些方面感到困惑。具体来说,我不明白我应该在哪里处理表单发送的数据。是在使用表单模板的视图上还是在另一个视图上?

例如,假设索引模板只有一个表单:

*index.html*
{% load url from future %}
<form action="{% url 'Directories:_results'%}" method="post">
Name: <input type="text" name="txtField" />
<input type="submit" name="submit" />
</form>

所以现在我认为我有两个版本:

#1 版本(1 个视图):同一个视图显示和处理表单

def index(request):
    if request.method == 'POST': # If the form has been submitted...
        form = dbForm(request.POST) # A form bound to the POST data
        if form.is_valid(): # All validation rules pass
            field = form.cleaned_data['txtField']
            #doSomething
    else:
        form = dbForm() #unbound form
     return render(request, 'Directories/index.html', {'form': form})

#2 版本(2 个视图):一个视图显示表单,一个视图处理表单数据

#the view that creates the form (unbound)
def index(request):
    form = dbForm()
    return render(request, 'Directories/index.html', {'form':form})

#the view that handles the data sent during form submission in the index template.
def results(request):
    if request.method == 'POST':
        form = dbForm(request.POST) # A form bound to the POST data
        if form.is_valid(): # All validation rules pass
            field = form.cleaned_data['txtField']
            #doSomething
     else:
         form = dbForm() #unbound form
     return render(request, 'Directories/index.html', {'form': form})

这是我的 urls.py:

from django.conf.urls import patterns, url
from Directories import views

urlpatterns = patterns('',
    url(r'^$', views.index, name='_index'),
    url(r'^results$', views.results, name='_results'),)

正如您所见,每个版本的数据处理方式都不同,因此我想知道其中是否有任何错误,如果两者都正确,那么哪个被认为是最佳实践。

【问题讨论】:

  • 不知道你为什么要问这个,真的。在版本 2 中,第二个视图与版本 1 的视图完全相同:那么版本 2 中的第一个视图有什么意义?
  • 对于这个过于简单的示例,第 2 版似乎是多余的,但我想了解的是在哪里处理数据?因此,我并没有试图强调示例本身,而是强调其背后的概念以及哪个版本被认为是最佳实践。例如,在一个更复杂的示例中,您必须处理多个表单,每个表单都有多个提交按钮,那么与版本 1 相比,版本 2 可以更好地分离关注点。我相信这取决于您正在处理的情况,但是我的问题更像是什么是规范

标签: django forms form-submit


【解决方案1】:

一般来说,表单会发布到显示它的同一个视图。

您可以像这样简化视图逻辑:

def index(request):
    form = dbForm(data=request.POST or None)
    if form.is_valid(): # All validation rules pass
        field = form.cleaned_data['txtField']
        #doSomething
        return redirect(success_url)
    return render(request, 'Directories/index.html', {'form': form})

请注意,如果您在成功发布表单后重定向通常会很好,即使您重定向回同一视图也是如此。这可以防止用户在刷新页面时被提示“重新发送表单数据”。

您应该查看在模板中呈现表单的文档:
https://docs.djangoproject.com/en/dev/topics/forms/#looping-over-the-form-s-fields

如果您不呈现字段错误,例如,用户将永远不会知道问题所在。

一个可以发布到不同视图的表单示例是,假设您的基本模板有一个“搜索”表单,该表单出现在每个页面上。当您发布此表单时,您不想返回当前视图,而是希望转到“搜索结果”视图。

【讨论】:

    【解决方案2】:

    两者都没有错,这取决于你想做什么。默认情况下,表单将数据发送到同一个请求,但如果这样更方便,您可以将数据发送到不同的视图

    在大多数情况下,使用相同的视图通常更简单。如果您使用外部工具\app\whatever,或者如果您想加强安全性(例如,让第二个视图只接受带有发布数据的请求等),则使用两个视图很好,但需要额外的步骤(错误处理,成功重定向)

    【讨论】:

      【解决方案3】:

      首先要理解的是,处理表单的视图通常也是首先显示表单的视图——因为它必须再次显示表单以防出错 .

      在您的模板中,您完全手动构建表单 HTML。这是不寻常的,因为如果出现错误(通常是未填写的必填字段),您希望再次呈现表单,所有已输入的值都存在,并带有很好的错误消息。 Django 的表单渲染({{ form.as_p }} 等)会为您执行此操作,如果您像这样手动编写 HTML,您不会得到它。事实上,你的观点错过了 is_valid() 上的 else: 子句,导致它进入

      所以通常视图会同时执行这两种操作,除了要理解的第二件事:在成功 POST 之后,您总是重定向到一个成功的页面,或者可能到同一个页面(这将显示一个空的再次形成)。主要是这样用户就不会意外地使用刷新按钮重新提交表单。

      所以你的第一个是典型的,除了你还需要在 is_valid() 情况下返回一个 ResponseRedirect ,并且应该在你的模板中呈现更多的表单。无需第二次查看。

      【讨论】:

        【解决方案4】:

        一般来说,一个view对应一个url。此外,相同的 url 应该显示表单并接受提交的表单。有了这个逻辑,你的第一种方法会更好。一个视图显示并接受表单。

        但是,在某些情况下,显示形式的视图与接受的形式不同。例如,具有多个表单的页面。每个表单都可以提交到不同的视图。但是可以实现不同的视图来处理该 url 并显示此类表单。

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2020-08-17
          • 2021-10-18
          • 1970-01-01
          • 2013-09-11
          • 2011-11-27
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多