2011-09-22 81 views
4

我们有一个现有的Django表单,它接受GET请求以允许用户为其生成的查询参数添加书签。该表格包含许多字段,其中大部分都是必需的。形式采用半标准的样板用于处理请求,POST取代GET:Django表单 - 处理GET请求

if request.method == 'GET': 
    form = myForm(request.GET) 
    if form.isValid() 
     # Gather fields together into query. 
else 
    form = myForm() 

的问题是,第一次加载窗体,没有什么在GET请求来填充必填字段,所以大部分表单都会显示'缺少字段'错误。

设置初始值不起作用;显然,GET请求中不存在的值会覆盖它们。

我们该如何避免这种情况?我很确定我们只是不正确地处理事情,但我找不到处理GET请求的表单示例。我们希望在用户点击“提交”按钮的同时字段为空或无效时出现错误,但不希望在最初显示表单时显示这些错误。

+0

为什么不使用request.POST和处理表单数据的标准方式? – Bobort

回答

3

forms.Form子类的位置参数告诉Django您打算处理表单而不是显示空白/默认表单。您的if request.method == 'GET'没有提供您想要的区别,因为通过在Web浏览器中输入网址或点击链接的常规旧网络请求也是GET请求,因此request.method等于GET

您需要一些区分机制,以便您可以区分表单显示和表单过程。

想法:

如果您的处理是通过。 AJAX,你可以使用if request.is_ajax()作为你的条件。

或者,您可以包含一个GET标记,表示请求正在处理。在这个例子中,首先你需要的东西在你的形式:

<input type="hidden" name="action" value="process_form" /> 

然后你可以看看你的观点,即值:

if 'action' in request.GET and request.GET['action'] == 'process_form': 
    form = myForm(request.GET) 
    if form.is_valid(): 
     # form processing code 
else: 
    form = myForm() 

我也会给你的标准,样板指出,如果你可以提供帮助,通常最好不要使用GET来进行表单处理(正因为你遇到了这样的困难,因为你使用了一个异常模式),但是如果你有一个真正需要它的用例,那么你真的需要它。你比我更了解你的需求。 :-)

+0

可悲的是,在这种情况下,我们真的需要它,根据我的老板。我们至少暂时通过使用两个URL解决了这个问题 - 第一个实例化表单,然后使用生成的GET请求调用第二个URL。第一个确保表单用其初始值填充,第二个将GET参数传递给表单的__init__例程。不漂亮,但又快又简单。 – SixDegrees

+0

我还没有到足够长的时间来回应你的反应,尽管我会尽可能。谢谢。 – SixDegrees

+0

我认为,如果你认为答案是正确的,那么接受的做法是“接受”它。 –

0

request.GET是空字典,当你第一次加载一个干净的表单。一旦提交了表单,即使字段只包含空数据,request.GET也会填充字段数据。

3

如果您的干净页面加载没有任何非表单GET参数,您可以区分干净的页面加载和表单提交您的视图。而不是通常的

form = YourForm() 
if request.POST: 

你可以做

if request.GET.items(): 
    form = YourForm(request.GET) 
    if form.is_valid(): 
     ... 

else: 
    form = YourForm() 

如果你干净的页面加载可能有其他PARAMS(如电子邮件中的链接追踪参数),你需要使用QueryDict methods来测试你的任何形式参数都在请求中。

0

我的第一个问题是这个,我发表评论: 为什么不只是使用request.POST和处理表单数据的标准方式?

在考虑了这里的所有内容后,或许您正在寻找的是处理查询字符串中的数据以填充表单的方式。您可以使用request.GET作为您的form.data

在我自己的看法中,我利用了我创建的一个实用函数来将初始数据添加到request.GET的表单中,但我不打算在此共享该函数。不过,这是签名。 initial_dict通常为request.GETmodel_forms可以是单个的ModelForm或是ModelForm的列表。

def process_initial_data(model_forms, initial_dict): 

尽管如此,我就能通过request.POST当表单发布的标准做法来处理形式。而且,我不必在URL查询字符串中传递各种信息,或者在用户输入信息时使用JavaScript对其进行修改。