2013-01-14 37 views
3

我想採取現成的形式(即從帶有驗證的綁定數據的django.Forms.form派生的類的對象),並將它作爲urlencode編碼,就像它使用GET一樣提交。有沒有內置的方法?我可以將Django表單轉換爲GET請求字符串嗎?

爲了說明爲什麼我要問這個問題,爲什麼我不能只叫urlencode,這個輸出應該是「box=on」。

from django import forms 
from urllib import urlencode 


class DemoForm(forms.Form): 
    box = forms.BooleanField(required=False) 

instance = DemoForm({"box": True}) # it's irrelevant how this data is supplied 
instance.is_valid() 
print "encoded:", urlencode(instance.cleaned_data) 

其實它的「box=True」,因爲urlencode未編碼的形式,它的編碼方式的清潔值(相信我,BooleanField是最簡單的情況下)。

所以我要求一種方式來編碼表單,就像它是一個GET字符串。一個正確的GET字符串。

回答

2

由於表單通常沒有任何關聯的值,我並不完全確定您對現成表單的含義。或者你的意思是採取一個用戶填寫的表格並將其張貼爲獲取?

您可以使用urllibs編碼創建一個GET字符串:

import urllib 

print urllib.urlencode({'key1': 'value1', 'key2': 'value2'}) 
# key1=value1&key2=value2 

如果你想利用提交的表單,並從這些數據創建一個GET字符串:

form = MyForm(request.POST) 
if form.is_valid(): 
    print urllib.urlencode(form.cleaned_data) 
    # name=value&name=value etc 

如果您想要爲未綁定的表單創建一個GET:

# this form contains intitial values 
# which are shown when printing the form 
form = MyForm() 
print urllib.urlencode(form.initial) 
# name=value&name=value etc 
+0

由現成的我的意思是從'django.Forms.form'派生的窗體類的實例。我會澄清這個問題。我知道如何用我自己的字典構建一個GET字符串,我想從基於其字段的驗證表單中完成。 – Joe

+0

恐怕我有點迷失在恰好當在這種形式的「流」中,這是假設發生的,但我已經用更多的例子更新了我的迴應。 –

+0

假設我有一個帶有綁定數據的驗證表單(即我稱之爲「is_valid」,響應爲「真」)。這是從數據構建和初始化的。這可能是構造函數中提供的初始數據,它可能來自POST數據,它可能來自任何東西。這個表單對象是如何創建的並不重要。我想生成一個GET url編碼的字符串,它表示如果我從瀏覽器提交表單,表單將如何提交。 – Joe

3

在表單的cleared_data上調用urllib的urlencode將無法正常工作在兩種情況下:

  • 如果使用的是ModelChoiceField,則清潔數據將包含實際對象,而不是ID。這些將urlencode()轉換爲它們的字符串表示形式,而不是它們的主鍵。
  • 如果您使用的字段可以保存多個值(例如MultiValueField,MultipleChoiceField或其他),則urlencode()將從該字段中丟失除該值之外的所有值。所以{'mykey':[1,2,3]}變成了mykey = 3而不是mykey = 1 & mykey = 2 & mykey = 3 django這樣做的方式。

爲了解決這兩個問題,使用窗體的內置功能進行urlencode:

form = MyForm(request.POST) #or a dict or whatever 
form.is_valid() 
querystring = form.data.urlencode() 

請注意,這就是所謂的數據,而不是cleaned_data。如果您的表單將值作爲驗證的一部分進行更改,則這些更改將不會反映在此處。

+0

這工作得很好,謝謝。請注意,如果表單中的數據是由POST生成的,那麼它可能會有一個csrfmiddlewaretoken,可能會被刪除。 – Chad

+1

如果現在有人絆倒了這一點,那麼在Django 1.10及更高版本中顯然不再支持。 '從django.utils.http導入urlencode; querystring = urlencode(form.data,doseq = True)' 會爲你做。 – umbrae

相關問題