2012-07-31 13 views
10

पर जानकारी वापस नहीं भेजता है मेरे पास मॉडलफॉर्म में एक ड्रॉपडाउन है और उपयोगकर्ता चयनित मान को बदलने में सक्षम नहीं होना चाहिए। मैंने पाया कि disabled बिल्कुल वही करता है जो मुझे चाहिए। हालांकि इसमें एक अजीबता है:Django: अक्षम ड्रॉपडाउन POST

पहली बार जब फॉर्म खुलता है (GET) मान चुना जाता है और उपयोगकर्ता मान को नहीं बदल सकता है। जो बहुत अच्छा है:

enter image description here

लेकिन जैसे ही वहाँ एक unrelated field के साथ एक मान्यता त्रुटि है और पोस्ट उसी रूप में वापस उपयोगकर्ता भेजता है के रूप में, पिछले जानकारी खो जाती है। विकलांग विदेशी-ड्रॉपडाउन में अब कोई मूल्य नहीं है और यह बहुत परेशान है।

enter image description here

मैं कुछ शोध किया और stackoverflow पर कुछ पाया है और जब एक foreignkey-लटकती विजेट अक्षम किया गया है, कोई डेटा सब पर वापस भेज दिया जाता है लगता है। जबकि third answer here बताते हैं कि ड्रॉपडाउन फ़ील्ड के लिए किसी भी त्रुटि को फेंकने के लिए सत्यापन को ओवरराइड किया जा सकता है। हालांकि यदि कोई अन्य असंबंधित फ़ील्ड कोई त्रुटि फेंकता है तो डेटा खो जाता है, क्योंकि अक्षम ड्रॉपडाउन ने पहले स्थान पर POST को कभी भी कोई डेटा नहीं भेजा था।

यह एक मुश्किल स्थिति है।

अनुरोध के लिए डेटा में पास करने का कोई तरीका है। POST? या आप क्या सुझाव देते हैं? मैं disabled के बजाय readonly का उपयोग कर सकता हूं और यह काम करेगा, हालांकि ड्रॉपडाउन उपयोगकर्ता द्वारा बदला जा सकता है, जो भी परेशान है।

कोई विचार? कई धन्यवाद

संपादित करें:

छोटे सुधार: डेटा पूरी तरह से समाप्त नहीं हुआ है। इसके बजाय चयन प्रारंभिक डमी मान में गलत तरीके से सेट किया गया है।

<select id="id_form-0-deal_type" name="form-0-deal_type" disabled="disabled"> 
     <option selected="selected" value="">---------</option> 
     <option value="1">deal 1</option> 
     <option value="2">deal 2</option> 
    </select> 

अद्यतन:

फ्रांसिस से समाधान बहुत आशाजनक दिखता है। इसलिए मैंने अपने दूसरे सुझाव की कोशिश की है और एचटीएमएल में एक छुपा इनपुटफील्ड जोड़ा है और पोस्ट में सही मूल्य में पास किया है।

समस्या अब आगे बढ़ना है। मैं इस तरह formset के फार्म का querydict में लापता प्रविष्टि जोड़ने के लिए

formset.forms[0].data['form-0-deal_type'] = formset.forms[0].data['form-0-hiddenfield'] 

(सही लटकती मूल्य सेट करने के लिए) की कोशिश की है लेकिन यह This QueryDict instance is immutable

इसे स्थापित कर रही है करने के लिए केवल दूसरी तरह कहते हैं नियमित प्रारूपों के साथ Initials के माध्यम से। दुर्भाग्यवश मैं मॉडल फॉर्मेट्स का उपयोग कर रहा हूं, जो doesn't support initials मौजूदा रूपों के लिए है।

यदि कोई अन्य समाधान नहीं है, तो मैं अपने मॉडलफॉर्मसेट को एक नियमित रूपरेखा में दोबारा शुरू करना शुरू करता हूं। विचारों के लिए अभी भी खुला ...

अंतिम अद्यतन + समाधान:

नियमित fomsets में modelformset refactor करने के लिए कोई जरूरत नहीं है। वास्तव में मैं इसे करने से बहुत हतोत्साहित करता हूं, क्योंकि यह स्वयं के साथ अन्य समस्याएं लाता है। मॉडलफॉर्मसेट आपके लिए सबकुछ संभालते हैं और गायब हिस्सों को भरते हैं।

वास्तविक समस्या तथ्य यह है कि QueryDict अपरिवर्तनीय हो रहा है, लेकिन यह आसानी से उन्हें कॉपी करके हल किया जा सकता:

formset = deal_formset(request.POST, queryset=formset_query)   
if formset.is_valid(): 
    pass 
else: 
    new_post = request.POST.copy() 
    deal_types = dict() 
    for k,v in new_post.items(): 
    if k.startswith('hidden'): 
     deal_types[k[7:]]= v 
    for k,v in deal_types.iteritems(): 
    new_post[k] = v 
    formset = deal_formset(new_post, queryset=formset_query) 

इस के साथ साथ फ्रांसिस के समाधान:

{{ formset.management_form }} 
    {% for fs in formset %} 
    {{ fs.id }} 
    <input type="hidden" name="hidden-{{ fs.prefix }}-deal_type" value="{{fs.deal_type.value}}" /> 
    {{fs.deal_type}} 
{% endfor %} 
{% endif %} 

सिर्फ चमत्कार काम करता है। .. आनंद लें :)

+1

"डेटा पूरी तरह से खो गया नहीं है।इसके बजाय चयन प्रारंभिक डमी मान में गलत तरीके से सेट किया गया है। "- वह बी/सी है कि फ़ील्ड पोस्ट नहीं हो रहा है। इसलिए डिफ़ॉल्ट मान –

उत्तर

17

यह एक django बात नहीं है, इसकी एक HTML चीज है। अक्षम फॉर्म तत्व फॉर्म द्वारा नहीं भेजे जाते हैं।

[तत्व] उपयोगकर्ता इनपुट प्राप्त नहीं कर सकता है और न ही उसका मान फ़ॉर्म के साथ सबमिट किया जाएगा।

http://www.w3.org/TR/html401/interact/forms.html#h-17.12.1 & http://www.w3schools.com/tags/att_input_disabled.asp

आप readonly इस्तेमाल कर सकते हैं अगर इसकी एक पाठ/पाठ क्षेत्र http://www.w3schools.com/tags/att_input_readonly.asp

कुछ और तुम कर सकते हो पर, मूल्य प्लेन टेक्स्ट दिखाने के है, और एक छिपी हुई फ़ील्ड के रूप में सबमिट करें। ...

{{ form.field_name.label_tag }} 
{{ form.field_name.value }} 
<input type="hidden" name="field_name" value="{{form.field_name.value}}" /> 

यह बहुत ही सुरुचिपूर्ण नहीं है, लेकिन यह वाई प्राप्त कर सकता है यहाँ से बाहर।

आप इसे एक कदम आगे भी ले जा सकते हैं और कुछ जेएस लिख सकते हैं जो अक्षम तत्वों की तलाश में हैं और उस तत्व के नाम और मूल्य के साथ इनपुट जोड़ते हैं।

कुछ नमूना JQuery:

//Untested, but you get the gist 
$(':disabled').each(
    function() 
    { 
     $(this).after('<input type="hidden" name="' + $(this).attr('name') + '" value="' + $(this).val() + '" />'); 
    } 
); 
+0

धन्यवाद फ्रांसिस है। महान समाधान। कृपया कुछ विवरण के साथ मेरा अपडेट किया गया प्रश्न देखें। धन्यवाद – Houman

0

मुझे लगता है कि इस बल्कि Django से, विकलांग प्रपत्र फ़ील्ड्स उनके मूल्यों वापस पोस्ट न करें एक HTML मुद्दा है ताकि आप मूल्य खो रहे हैं।

सत्यापन विफल होने पर फ़ील्ड के मान को पुन: स्थापित करना संभव होगा? आप की तरह

if form.is_valid(): # All validation rules pass 
    #save form, redirect, etc. 
else: 
    form.disabled_field = my_value 
return render(request, 'contact.html', {'form': form,}) 

कुछ की कोशिश कर सकते जाहिर है आप अपने मॉडल से सही डेटा के साथ क्षेत्र का नाम और मान को बदलने के लिए की आवश्यकता होगी।

1

ठीक है, आप टेम्पलेट में छिपा संपत्ति के साथ तत्व सेट कर सकते हैं, को ध्यान में रखते formsets का उपयोग कर प्रपत्र का निर्माण करने की:

{{form.field.as_hidden}} 

और देखने के अंदर, यदि समस्या डेटा हानि है, तो आप कर सकते थे हमेशा उस मॉडल के लिए प्रारंभिक मान सेट करें जो आपके मॉडल संरचना के अनुरूप है, क्योंकि यह एक विदेशी कुंजी है। बेशक, आपको इसे करने से पहले फॉर्म को सत्यापित करना होगा, और यदि फॉर्म वैध नहीं है, तो आप इसे उन फ़ील्ड पर प्रारंभिक मानों के साथ प्रस्तुत कर सकते हैं जिन्हें हमेशा भरना होगा।

+0

मुझे विचार पसंद है। मुझे छिपे हुए हिस्से को समझ में नहीं आया, क्योंकि मैं स्पष्ट रूप से डिफ़ॉल्ट चयन को खो रहा हूं। इसलिए मुझे इसे किसी भी तरह से देखने के लिए भेजना है। मैं इसे एक अतिरिक्त छिपे इनपुट क्षेत्र के फ्रांसिस के सुझावों के साथ करने में कामयाब रहा। और वहां से मैं वास्तव में प्रारूपों पर प्रारंभिक के बारे में सोच रहा था। :) कृपया मेरे अपडेट किए गए प्रश्न पर एक नज़र डालें। धन्यवाद :) – Houman

+1

एक्सेलेंट! मैं इस सवाल को अपने पसंदीदा में रखूंगा, क्योंकि मैं भविष्य में ऐसी स्थिति से निपट सकता हूं ! –

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