मैं दो ड्रॉपडाउन के साथ एक साधारण यूजर इंटरफेस बना रहा हूं। पहले ड्रॉपडाउन में जो चुना गया है उसके आधार पर, दूसरा ड्रॉपडाउन jQuery/AJAX के माध्यम से कुछ नए मानों से भरा हुआ है। समस्या यह है कि जब फॉर्म जमा किया जाता है, तो फॉर्म सत्यापन ठीक से विफल हो जाता है क्योंकि दूसरी ड्रॉपडाउन में विकल्प जो वापस आता है वह उस सूची में नहीं था जिसने पहली बार ड्रॉपडाउन उत्पन्न किया था।

फॉर्म को सत्यापित करने से पहले ड्रॉपडाउन 2 से जो भी डेटा भेजा गया था, उसे फॉर्म ऑब्जेक्ट में इंजेक्ट करके मैंने इसे काम करने के लिए प्राप्त कर लिया है। यह कोड नीचे दिखाया गया है, लेकिन यह एक हैकी समाधान की तरह लगता है।

form = SearchForm(request.form)

# dropdown 1
form.node_type.choices = [('default', 'Please select a node type')]
form.node_type.choices.extend([(t, t) for t in node_types()])

# dropdown 2
form.node_name.choices = [('default', 'Select a node type first')]

if request.method == 'POST':
    # the below 2 lines are the hack that make it work.
    node_name = request.form.get('node_name')
    form.node_name.choices.append((node_name, node_name))

    if form.validate():
        print('hooray')

क्या क्लाइंट-साइड पर विकल्पों को गतिशील रूप से जोड़ने के लिए कोई मानक/अनुशंसित तरीका है और अभी भी WTForms फॉर्म सत्यापन को ठीक से करते हैं?

2
toppatopvt 31 मई 2019, 15:14

1 उत्तर

सबसे बढ़िया उत्तर

यह एक शुद्ध wtforms समाधान है, लेकिन फ्लास्क-wtf (फ्लास्क-wtf कॉल form.validate() के भीतर form.validate_on_submit()) के साथ काम करना चाहिए।

यदि node_name फ़ील्ड 'वैध विकल्प नहीं' त्रुटि के साथ सत्यापन विफल हो गया है, तो कस्टम सत्यापन फ़ंक्शन को कॉल करने के लिए कोड Form.validate का विस्तार करता है। यदि सत्यापन फ़ंक्शन True लौटाता है, तो यह Form.errors से 'मान्य विकल्प नहीं' त्रुटि को हटाता है और True लौटाता है यदि Form.errors अब खाली है।

import werkzeug
import wtforms


class Form(wtforms.Form):

    node_type = wtforms.SelectField(choices=[(x, x) for x in 'ABCDEF'])
    node_name = wtforms.SelectField(choices=[('', '')])

    def validate(self):
        if super().validate():
            return True
        invalid_choice = 'Not a valid choice'
        if 'node_name' in self.errors and invalid_choice in self.errors['node_name']:
            is_valid_node_name = self.cross_validate_node_name()
            if is_valid_node_name:
                self.errors['node_name'].remove(invalid_choice)
                if not self.errors['node_name']:
                    del self.errors['node_name']
                return not self.errors
        return False

    def cross_validate_node_name(self):
        # Implement your validation logic here.
        return self.node_type.data == 'B' and self.node_name.data == 'spam'


if __name__ == '__main__':
    datas = [werkzeug.MultiDict([('node_type', 'A'), ('node_name', 'spam')]),
             werkzeug.MultiDict([('node_type', 'B'), ('node_name', 'spam')])]
    for data in datas:
        form = Form(formdata=data)
        if form.validate():
            print('OK')
        else:
            print(form.errors)
2
snakecharmerb 1 जून 2019, 10:13