Cookies op Tweakers

Tweakers is onderdeel van DPG Media en maakt gebruik van cookies, JavaScript en vergelijkbare technologie om je onder andere een optimale gebruikerservaring te bieden. Ook kan Tweakers hierdoor het gedrag van bezoekers vastleggen en analyseren. Door gebruik te maken van deze website, of door op 'Cookies accepteren' te klikken, geef je toestemming voor het gebruik van cookies. Wil je meer informatie over cookies en hoe ze worden gebruikt? Bekijk dan ons cookiebeleid.

Meer informatie
Toon posts:

[Python] Krijg Flask FormField RequiredIf niet werkend

Pagina: 1
Acties:

Vraag


  • Tristan
  • Registratie: maart 2002
  • Laatst online: 14-06 09:13
Ik heb problemen met het volgende:

Ik gebruik Flask met Flask-WTF en nu moet ik bepaalde velden verplicht maken als een ander veld (niet) een bepaalde waarde heeft.

Ik heb dit werkend voor de velden in dezelfde class. Echter voor velden die niet in dezelfde class zitten maar worden geerfd vanuit een andere class via een FormField() + FormList() methode werkt het niet.

Ik zie twee problemen.

1) country_code is niet bekend in de ItemsForm() class, die velden moeten dus op de een of andere manier bij MainForm() moeten kunnen komen.

2) De RequiredIfNot() __call__ methode krijgt niet het juist form mee voor de velden in ItemsForm(). Waardoor het dus ook nooit tegen de juiste country_code waarde kan checken.

(De var COUNTRIES is gevuld)

code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
class RequiredIfNot(DataRequired):
    """Validator which makes a field required if another field is set and has a truthy value.
    Sources:
        - http://wtforms.simplecodes.com/docs/1.0.1/validators.html
        - http://stackoverflow.com/questions/8463209/how-to-make-a-field-conditionally-optional-in-wtforms
        - https://gist.github.com/devxoul/7638142#file-wtf_required_if-py
    """
    field_flags = ('requiredif',)
    def __init__(self, message=None, *args, **kwargs):
        super(RequiredIfNot).__init__()
        self.message = message
        self.conditions = kwargs
    # field is requiring that name field in the form is data value in the form
    def __call__(self, form, field):
        for name, data in self.conditions.items():
            other_field = form[name]
            if other_field is None:
                raise Exception("No field named {} in form".format(name))
            if other_field.data != data and not field.data:
                DataRequired.__call__(self, form, field)
            Optional()(form, field)

class ItemsForm(FlaskForm):
    item_description = StringField(
        'Item description', [
            RequiredIfNot(country_code="DE", message='Item description is required')
        ]
    )

class MainForm(FlaskForm):
    country_code = SelectField(
        'Destination country', [
            validators.Required()
        ],
        choices=COUNTRIES,
        default = "DE"
    )
    number = StringField(
        'Invoice number', [
            RequiredIfNot(country_code="DE", message='Invoice number is required')
        ]
    )
    items = FieldList(
        FormField(ItemsForm),
        min_entries=1
    )

...

Python 3.8.2
Flask 1.1.2
Flask-WTF 0.14.3
...

Ik heb van alles geprobeerd in de RequiredIf() functie maar ik zie niet hoe ik daar de juiste form object meekrijg.

Mainform.country_code="DE" opgeven geeft een error:
SyntaxError: keyword can't be an expression
...

Alle reacties


  • Barreljan
  • Registratie: december 2001
  • Laatst online: 13:17

Barreljan

...Zoom-Zoom...

Zit het 'm niet in regel 36, de extra spaties rond de '=' ?

Specs pjoeter
Time Attacker met de Mazda 323F 2.5 V6 J-spec | PV output


  • Tristan
  • Registratie: maart 2002
  • Laatst online: 14-06 09:13
Barreljan schreef op woensdag 17 juni 2020 @ 09:56:
Zit het 'm niet in regel 36, de extra spaties rond de '=' ?
Hmm, ik zal het testen, maar om je gedachte te begrijpen waarom zou dat uitmaken?

  • Tristan
  • Registratie: maart 2002
  • Laatst online: 14-06 09:13
Hier is de stack trace

code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
  File "/Users/tvb/Library/Python/3.7/lib/python/site-packages/flask/app.py", line 1950, in full_dispatch_request
    rv = self.dispatch_request()
  File "/Users/tvb/Library/Python/3.7/lib/python/site-packages/flask/app.py", line 1936, in dispatch_request
    return self.view_functions[rule.endpoint](**req.view_args)
  File "/Users/tvb/code/common/decorators.py", line 92, in wrap
    return f(*args, **kwargs)
  File "/Users/tvb/code/common/decorators.py", line 154, in wrap
    return f(*args, **kwargs)
  File "/Users/tvb/code/common/decorators.py", line 144, in wrap
    return f(*args, **kwargs)
  File "/Users/tvb/code/main/routes.py", line 208, in main_add_copy_edit
    if form.validate_on_submit():
  File "/Users/tvb/Library/Python/3.7/lib/python/site-packages/flask_wtf/form.py", line 100, in validate_on_submit
    return self.is_submitted() and self.validate()
  File "/Users/tvb/Library/Python/3.7/lib/python/site-packages/wtforms/form.py", line 310, in validate
    return super(Form, self).validate(extra)
  File "/Users/tvb/Library/Python/3.7/lib/python/site-packages/wtforms/form.py", line 152, in validate
    if not field.validate(self, extra):
  File "/Users/tvb/Library/Python/3.7/lib/python/site-packages/wtforms/fields/core.py", line 941, in validate
    if not subfield.validate(form):
  File "/Users/tvb/Library/Python/3.7/lib/python/site-packages/wtforms/fields/core.py", line 823, in validate
    return self.form.validate()
  File "/Users/tvb/Library/Python/3.7/lib/python/site-packages/wtforms/form.py", line 310, in validate
    return super(Form, self).validate(extra)
  File "/Users/tvb/Library/Python/3.7/lib/python/site-packages/wtforms/form.py", line 152, in validate
    if not field.validate(self, extra):
  File "/Users/tvb/Library/Python/3.7/lib/python/site-packages/wtforms/fields/core.py", line 206, in validate
    stop_validation = self._run_validation_chain(form, chain)
  File "/Users/tvb/Library/Python/3.7/lib/python/site-packages/wtforms/fields/core.py", line 226, in _run_validation_chain
    validator(form, self)
  File "/Users/tvb/code/main/forms.py", line 68, in __call__
    other_field = form[name]
  File "/Users/tvb/Library/Python/3.7/lib/python/site-packages/wtforms/form.py", line 65, in __getitem__
    return self._fields[name]
KeyError: 'country_code'

  • Barreljan
  • Registratie: december 2001
  • Laatst online: 13:17

Barreljan

...Zoom-Zoom...

Tristan schreef op woensdag 17 juni 2020 @ 10:33:
[...]


Hmm, ik zal het testen, maar om je gedachte te begrijpen waarom zou dat uitmaken?
code:
1
2
3
4
5
6
7
8
9
10
11
12
    country_code = SelectField(
        'Destination country', [
            validators.Required()
        ],
        choices=COUNTRIES,
        default = "DE"
    )
    number = StringField(
        'Invoice number', [
            RequiredIfNot(country_code="DE", message='Invoice number is required')
        ]
    )


Als je die 2 verschillende zaken bekijkt, roep je 2x een functie/class aan, waarbij je dus wel de invoer goed moet doen. Als je die even lang uit zet zie je het verschil. Je stuurt nu geen keyword met een arg mee, maar je maakt er andere soep van (op bijv een manier om een string object te definiëren)

country_code = SelectField('Destination country', [validators.Required()], choices=COUNTRIES, default = "DE")

en

number = StringField('Invoice number', [RequiredIfNot(country_code="DE", message='Invoice number is required')])

in short:

iets = TestFunctie('boe', key1='arg1', key2='arg2')


Als ik het goed heb, ik ben er even paar weken er tussenuit geweest.

Specs pjoeter
Time Attacker met de Mazda 323F 2.5 V6 J-spec | PV output


  • DaFeliX
  • Registratie: december 2002
  • Laatst online: 12:42

DaFeliX

Tnet Devver
Tristan schreef op woensdag 17 juni 2020 @ 09:07:

[...]

Ik heb van alles geprobeerd in de RequiredIf() functie maar ik zie niet hoe ik daar de juiste form object meekrijg.

Mainform.country_code="DE" opgeven geeft een error:


[...]

...
Ja, want Mainform is een class, waar je country_code in wil aanpassen. Je moet eerst een instantie van die class maken, dus mainform = new Mainform(), dan kun je mainform.country_code = "DE" doen.

Einstein: Mijn vrouw begrijpt me niet


  • Tristan
  • Registratie: maart 2002
  • Laatst online: 14-06 09:13
DaFeliX schreef op woensdag 17 juni 2020 @ 11:05:
[...]


Ja, want Mainform is een class, waar je country_code in wil aanpassen. Je moet eerst een instantie van die class maken, dus mainform = new Mainform(), dan kun je mainform.country_code = "DE" doen.
Ik snap waar je heen wilt, maar ik moet de "gesubmitte" class aanroepen ipv een nieuwe initiëren anders is country_code "DE" en niet bijvoorbeeld "BR" als ik Brazilië heb geselecteerd in mijn form.

[edit]
@DaFeliX volgens mij is
code:
1
form = new Mainform()
geen valide Python code.

Maar met form = Mainform() krijg ik
RequiredIfNot(form.country_code="NL", message='Item description is required')
^
SyntaxError: keyword can't be an expression

[Voor 21% gewijzigd door Tristan op 17-06-2020 11:26]


  • DaFeliX
  • Registratie: december 2002
  • Laatst online: 12:42

DaFeliX

Tnet Devver
Tristan schreef op woensdag 17 juni 2020 @ 11:13:
[...]

@DaFeliX volgens mij is
code:
1
form = new Mainform()
geen valide Python code.
Nee sorry, dat moet natuurlijk mainform = Mainform() zijn 8)7 ik moet minder tussen talen switchen
Tristan schreef op woensdag 17 juni 2020 @ 11:13:
[...]

RequiredIfNot(form.country_code="NL", message='Item description is required')

[...]
Dit staat niet in je topicstart? Maar nee, dat lijkt mij geen valide syntax want je geeft een argument voor een parameter "form.country_code" op, maar dat is geen geldige parameternaam, dat zou dan country_code="NL" moeten zijn

Einstein: Mijn vrouw begrijpt me niet


  • Tristan
  • Registratie: maart 2002
  • Laatst online: 14-06 09:13
DaFeliX schreef op woensdag 17 juni 2020 @ 12:01:
[...]
Dit staat niet in je topicstart? Maar nee, dat lijkt mij geen valide syntax want je geeft een argument voor een parameter "form.country_code" op, maar dat is geen geldige parameternaam, dat zou dan country_code="NL" moeten zijn
Nee klopt, maar dat stel jij toch voor?
Pagina: 1


Apple iPad Pro (2021) 11" Wi-Fi, 8GB ram Microsoft Xbox Series X LG CX Google Pixel 5a 5G Sony XH90 / XH92 Samsung Galaxy S21 5G Sony PlayStation 5 Nintendo Switch Lite

Tweakers vormt samen met Hardware Info, AutoTrack, Gaspedaal.nl, Nationale Vacaturebank, Intermediair en Independer DPG Online Services B.V.
Alle rechten voorbehouden © 1998 - 2021 Hosting door True