2011-06-11 10 views
5

में POST शब्दकोश को पोस्ट करता है मैं django में परीक्षण क्लाइंट का उपयोग करते समय वास्तव में विचित्र व्यवहार का अनुभव कर रहा हूं।डैंजो के प्रश्नोत्तरी विचित्र व्यवहार: एक एकल कुंजी

मैं अपने django ऐप में डेटा भेजने के लिए POST का उपयोग कर रहा हूं। मैं आमतौर पर इसे एक आईफोन ऐप और/या एक परीक्षण एचटीएमएल फॉर्म से करता हूं। सर्वर साइड पर यह है कि कैसे मैं इसे संभाल:

प्रिंट बयान आप उम्मीद करेंगे क्या, यानी पोस्ट अनुरोध में प्रत्येक पैरामीटर शब्दकोश में एक महत्वपूर्ण में बदल गया है की तरह लग रहा
def handle_query(request): 
    print request 
    q = con.QueryLog() 
    q.ID = request.POST.get('ID', '') 
    q.device = request.POST.get('device-model', '') 
    .... 

कि:

पोस्ट : QueryDict: {u'app-version ': [u'3.0'], u'server-version ': [u'v3d0'],

हालांकि, मैंने Django के परीक्षण क्लाइंट का उपयोग करके कुछ परीक्षण लिखना शुरू किया, और नहीं जो भी मैं कोशिश करता हूं, पोस्ट अनुरोध में भेजे गए POST पैरामीटर का शब्दकोश QueryDict में एक ही कुंजी में बंधा हुआ है।

वर्ग SearchTest (testcase): डीईएफ़ सेटअप (स्वयं): मुझे कुछ कोड के साथ उदाहरण देकर स्पष्ट करने की अनुमति दें पास

def test_search(self): 
    request = HttpRequest() 
    data = '{"amzn_locale": "com"}' 
    # request._raw_post_data = data 
    resp = self.client.post(
     '/is/', 
     data=data, 
     content_type='application/x-www-form-urlencoded', 
     # content_type='application/json', 
     ) 

सर्वर साइड पर एक ही प्रिंट बयान में शब्दकोश का अकथनीय समूह से पता चलता एक स्ट्रिंग:

POST: QueryDict: {u'{"amzn_locale":"com"}': [u'']}>, 

अगर मैं एक वास्तविक शब्दकोश में डेटा सेट, एक ही बात

data = {"amzn_locale": "com"} 

अनुरोध सेट करना ._raw_post_data कुछ भी नहीं बदलता है। न ही

content_type='application/json' 

किसी भी मदद की बहुत सराहना की जाएगी। इस stackoverflow सवाल से ऐसा लगता है जैसे मैं इस iphone Json POST request to Django server creates QueryDict within QueryDict

+0

गैबी संपादन – Andres

उत्तर

7

समस्या यह है कि आप एक content_type उपलब्ध करा रहे है। जब से तुम वैसा ही किया, ग्राहक की तरह

{'username': 'hi', 'password': 'there', 'this_is_the_login_form': 1} 

तरह

"username=hi&password=there&this_is_the_login_form=1" 
एक शब्दकोश के बजाय

एक urlencoded स्ट्रिंग की उम्मीद है आप content_type kwarg आप ठीक हो जाओगे निकालते हैं।

संपादित करें: जैसा कि यह पता चला है, परीक्षण क्लाइंट यूआरएल-एन्कोडेड स्ट्रिंग की तलाश करेगा यदि आप MULTIPART_CONTENT के अलावा किसी भी सामग्री_टाइप में पास करते हैं - सामग्री_ प्रकार का उपयोग केवल यह पता लगाने के लिए किया जाएगा कि उस यूआरएल को एन्कोड करने के लिए किस वर्ण का उपयोग करना है- एन्कोडेड स्ट्रिंग। यह here दस्तावेज है। प्रासंगिक बिट पढ़ता है:

आप content_type प्रदान करते हैं (उदाहरण के लिए, एक XML पेलोड के लिए text/xml), डेटा की सामग्री पोस्ट अनुरोध के रूप में-है, HTTP सामग्री प्रकार में content_type उपयोग करके भेजा जाएगा हैडर।

आप content_type के लिए एक मूल्य प्रदान नहीं करते हैं, तो डेटा के मानों बहुखण्डीय/फार्म डेटा की किसी सामग्री प्रकार के साथ प्रसारित किया जाएगा। इस मामले में, डेटा में कुंजी-मूल्य जोड़े को मल्टीपार्ट संदेश के रूप में एन्कोड किया जाएगा और पोस्ट डेटा पेलोड बनाने के लिए उपयोग किया जाएगा।

+0

सहायता के लिए धन्यवाद;) – Andres

0

में चलाने के लिए पहले एक नहीं कर रहा हूँ लेकिन अगर आप एक स्ट्रिंग के रूप में यह घोषणा की - आप data के लिए मूल्य के आसपास एकल उद्धरण है।

+0

संपादन के लिए धन्यवाद इससे कोई फर्क नहीं पड़ता, डेटा जमा करने का दूसरा तरीका देखें। यहां तक ​​कि समूहबद्ध हो जाता है। – Andres

1

संपादित करें: और निश्चित रूप से उस रेखा के ठीक ऊपर जिस रेखा पर मैंने देखना शुरू किया वह सही जवाब है। content_data को content_type के आधार पर अलग-अलग संभाला जाता है। नीचे जवाब देखें। नीचे परिवर्तन लागू करने की जरूरत नहीं है।

तो ऐसा लगता है कि क्या हो रहा है यह है कि आपके द्वारा पोस्ट किए जाने वाले डेटा निर्देश को स्ट्रिंग एन्कोडिंग फ़ंक्शन द्वारा तुरंत स्ट्रैट एन्कोडिंग फ़ंक्शन द्वारा फ़्लैट किया जा रहा है, जो बाद में लाइन के नीचे क्वेरीडिक्ट पढ़ नहीं सकता है। मुझे नहीं पता कि इच्छित व्यवहार क्या है, लेकिन यदि आप धारावाहिक प्राप्त करने से पहले पोस्ट डेटा urlencode तो कम से कम QueryDict पर आवश्यक फॉर्म में आना चाहिए। Django/test/client.py में हम लाइन 244

post_data = smart_str(data, encoding=charset) 

जो सिर्फ ताना को धक्का देता है और इसे क्रमबद्ध करता है। एक संभव समाधान प्राप्त क्रमबद्धता से पहले का उपयोग करता है के रूप में है, इसलिए

post_data = smart_str(urlencode(data, doseq=True), encoding=charset) 

यह मेरे लिए उचित लगता है हालांकि मैं गारंटी नहीं दे सकते हैं कि यह परिणाम कहीं और नहीं है एक ही स्वरूपण लागू होगा। ऐसा लगता है कि आप क्लाइंट.post पर कॉल से पहले अपने कोड में उपरोक्त परिवर्तन कर सकते हैं, लेकिन मैंने इसका परीक्षण नहीं किया है।

संबंधित मुद्दे