किसी प्रपत्र के प्रारंभ होने के बाद Django सेट फ़ील्ड मान


116

मैं प्रपत्र के आरंभ होने के बाद फ़ील्ड को एक निश्चित मान पर सेट करने का प्रयास कर रहा हूं।

उदाहरण के लिए, मेरे पास निम्न वर्ग है।

class CustomForm(forms.Form):
    Email = forms.EmailField(min_length=1, max_length=200)

देखने में, मैं ऐसा कुछ करने में सक्षम होना चाहता हूं:

form = CustomForm()
form["Email"] = GetEmailString()

return HttpResponse(t.render(c))

जवाबों:


135

चूंकि आप POST डेटा में पास नहीं हो रहे हैं, इसलिए मैं मान लूंगा कि आप जो करने की कोशिश कर रहे हैं वह एक प्रारंभिक मूल्य है जिसे फॉर्म में प्रदर्शित किया जाएगा। आपके द्वारा ऐसा करने का तरीका initialकीवर्ड के साथ है ।

form = CustomForm(initial={'Email': GetEmailString()})

अधिक विवरण के लिए Django फॉर्म डॉक्स देखें ।

यदि आप फ़ॉर्म सबमिट करने के बाद किसी मान को बदलने का प्रयास कर रहे हैं, तो आप कुछ का उपयोग कर सकते हैं:

if form.is_valid():
    form.cleaned_data['Email'] = GetEmailString()

उपयोग करने पर अधिक के लिए ऊपर संदर्भित डॉक्स देखें cleaned_data


2
यह पुष्टि करता है कि मुझे क्या पता था, लेकिन ModelChoiceFieldजब मैं इसे एक initialमूल्य देता हूं, तो मेरा अभी भी
अमान्य_कॉपी

हां, यह मेरी समस्या है। और form.data ['ईमेल'] को बदलना संभव नहीं है।
गार्ग्यलीपोलैंकै

2
मैंने उसे बदल दिया form.data['Email'] = GetEmailString()और यह काम करता है
मनोवैज्ञानिक 7

1
मुझे इसे CustomForm (request.POST) और .is_valid () के बीच सेट करने की आवश्यकता है , इसलिए मैं कंस्ट्रक्टर में न तो प्रारंभिक उपयोग कर सकता हूं, न ही क्लीनड_डेटा। मैंने form.data का उपयोग करने की कोशिश की, लेकिन यह अपरिवर्तनीय है (Django 1.11)।
तेईकिन

इस सवाल का सही समाधान, होना चाहिए: आप के बाद भी अपने प्रपत्र instanciated होने अपने मूल्यों प्रारंभ करने में पहुँच देता हैform.fields['Email'].initial = GetEmailString()form.fields['keyword'].initial
vctrd

95

यदि आपने पहले ही फॉर्म को इनिशियलाइज़ कर लिया है, तो आप फ़ील्ड की प्रारंभिक प्रॉपर्टी का उपयोग कर सकते हैं। उदाहरण के लिए,

form = CustomForm()
form.fields["Email"].initial = GetEmailString()

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

5
क्या ऐसा करने का कोई अलग तरीका है Django 1.7 / Python 3.4? यह मेरे लिए काम नहीं कर रहा है
जेरेमी

1
@JeremyCraigMartinez: नहीं ... क्या आप एक बाध्य प्रपत्र (GET / POST डेटा पास होने के साथ) आज़मा रहे हैं? डॉक्स कहते हैं यही कारण है कि प्रारंभिक मान केवल अनबाउंड रूपों के लिए प्रदर्शित किए जाते हैं। बाध्य रूपों के लिए, HTML आउटपुट बाध्य डेटा का उपयोग करेगा। , यहाँ
मार्कस

9
सही तरीका है form.initial ["Email"] = GetEmailString ()
एलियो स्कोर्डो

12

यदि आप इसे __init__किसी कारण से फार्म की विधि के भीतर करना चाहते हैं , तो आप initialतानाशाही में हेरफेर कर सकते हैं :

class MyForm(forms.Form):
    my_field = forms.CharField(max_length=255)

    def __init__(self, *args, **kwargs):
        super(MyForm, self).__init__(*args, **kwargs)
        self.initial['my_field'] = 'Initial value'

अंत में समाधान मिल गया। धन्यवाद। यह मेरे लिए काम किया है।
अल्मास दुसाल

8

निगेल कोहेन की तरह कुछ काम करेगा यदि आप फॉर्म डेटा के एकत्रित सेट की एक प्रति में डेटा जोड़ रहे हैं :

form = FormType(request.POST)
if request.method == "POST":
    formcopy = form(request.POST.copy())
    formcopy.data['Email'] = GetEmailString()

1
मैं कच्चे डेटा को ओवरराइड करने का बड़ा प्रशंसक नहीं हूं। यदि आपको पूरी तरह से ऐसा करना है, तो आपको संभवतः उन data[form.add_prefix('Email')]मामलों के लिए खाता होना चाहिए जहां एक उपसर्ग सेट किया गया है।
जोश

2
क्या ऐसा करने का कोई अलग तरीका है Django 1.7 / Python 3.4? यह मेरे लिए काम नहीं कर रहा है
जेरेमी

तीसरी पंक्ति थोड़ी छोटी हो सकती है यदि मूल रूप रखने की कोई आवश्यकता नहीं है:form.data = form.data.copy()
ZZY

@ जोश, यहां जरूरत का एक परिदृश्य है: इनपुट को मान्य करने के लिए एक फॉर्म का उपयोग करें -> इनपुट के साथ प्रसंस्करण -> प्रसंस्करण किया -> फार्म के कई क्षेत्रों को मिटा दें / संशोधित करें और प्रतिक्रिया के रूप में HTML को प्रस्तुत करें। उदाहरण के लिए, 'नाम', 'ईमेल', 'सामग्री' फ़ील्ड एक रूप में हैं, मैं 'नाम' और 'ईमेल ’रखना चाहता हूं, लेकिन' सामग्री 'मिटा देता हूं। ताकि उपयोगकर्ताओं को फिर से नाम / ईमेल इनपुट करने की आवश्यकता न हो, यदि वे एक और POST जमा करना चाहते हैं। निश्चित रूप से एक ही नाम / ईमेल के साथ एक नया रूप इनिशियलाइज़ करें, इनिशियल वैल्यू एक तरीका है, लेकिन मुझे लगता है कि पुराने रूप को मिटाना कुछ मामलों में सरल है
ZZY

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

5

अगर आपने फॉर्म को इस तरह से इनिशियलाइज़ किया है

form = CustomForm()

फिर जनवरी 2019 तक सही तरीका , .initialडेटा को बदलने के लिए उपयोग करना है। यह intialउस फॉर्म में मौजूद डेटा को बदल देगा जो फॉर्म के साथ जाता है। यह भी काम करता है यदि आपने कुछ उदाहरणों का उपयोग करके इनिशियलाइज़ किया है form = CustomForm(instance=instance)

प्रपत्र में डेटा को बदलने के लिए, आपको करने की आवश्यकता है

form.initial['Email'] = GetEmailString()

इसे सामान्य बनाते हुए,

form.initial['field_name'] = new_value

3

बस अपना Form.data फ़ील्ड बदलें:

class ChooseProjectForm(forms.Form):
    project = forms.ModelChoiceField(queryset=project_qs)
    my_projects = forms.BooleanField()

    def __init__(self, *args, **kwargs):
        super(ChooseProjectForm, self).__init__(*args, **kwargs)
        self.data = self.data.copy()  # IMPORTANT, self.data is immutable
        # any condition:
        if self.data.get('my_projects'):
            my_projects = self.fields['project'].queryset.filter(my=True)
            self.fields['project'].queryset = my_projects
            self.fields['project'].initial = my_projects.first().pk
            self.fields['project'].empty_label = None  # disable "-----"
            self.data.update(project=my_projects.first().pk)  # Update Form data
            self.fields['project'].widget = forms.HiddenInput()  # Hide if you want

0

मिश्रण में अभी तक एक और रास्ता फेंकने के लिए: यह भी काम करता है, थोड़ा अधिक आधुनिक अंकन के साथ। यह सिर्फ इस तथ्य के आसपास काम करता है कि एक QueryDictअपरिवर्तनीय है।

>>> the_form.data = {**f.data.dict(), 'some_field': 47}
>>> the_form['some_field'].as_widget()
'<input type="hidden" name="some_field" value="47"
        class="field-some_field" id="id_some_field">'

0

विजेट में 'मूल्य' attr का उपयोग करें। उदाहरण:

username = forms.CharField(
    required=False,
    widget=forms.TextInput(attrs={'readonly': True, 'value': 'CONSTANT_VALUE'}),
)

-12

ऐसा करने का एक और तरीका है, यदि आपने पहले ही एक फॉर्म (डेटा के साथ या बिना) को इनिशियलाइज़ कर लिया है, और आपको डेटा भेजने से पहले और डेटा जोड़ना होगा:

form = Form(request.POST.form)
form.data['Email'] = GetEmailString()

8
यह मेरे लिए विफल है। मेरे पास मेरे फॉर्म की init पद्धति में ऊपर की तरह एक लाइन है , और यह "AttributeError: This QueryDict आवृत्ति अपरिवर्तनीय है"
जोनाथन हार्टले

यह कोड केवल तभी काम करता है जब फॉर्म को बिना किसी फॉर्म डेटा के आरंभ किया गया हो। परिणामस्वरूप, एक अपरिवर्तनीय वस्तु जैसे request.GET या request.POST बाध्य नहीं होगी, इसलिए आपको एक खाली शब्दकोश (form.data) मिलेगा, जिसे बिना किसी त्रुटि के बदला जा सकता है। FYI करें मैं उपयोग कर रहा हूँ Django 1.6.3
potar

यह तब काम करेगा जब आपका "कंटेंट-टाइप" हेडर "मल्टीपार्ट / फॉर्म-डेटा" पर सेट हो। जब आप "एप्लिकेशन / x-www-form-urlencoded" सामग्री-प्रकार का उपयोग करते हैं तो यह विफल हो जाता है। मुझे पता नहीं क्यों, लेकिन यह डिबग करने के लिए एक ***** था।
तेयुएन
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.