File: validators.rst

package info (click to toggle)
wtforms-alchemy 0.19.0-3
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid
  • size: 492 kB
  • sloc: python: 3,955; makefile: 119; sh: 11
file content (230 lines) | stat: -rw-r--r-- 6,288 bytes parent folder | download | duplicates (3)
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
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
Validators
==========


Auto-assigned validators
------------------------

By default WTForms-Alchemy ModelForm assigns the following validators:
    * InputRequired validator if column is not nullable and has no default value
    * DataRequired validator if column is not nullable, has no default value and is of type `sqlalchemy.types.String`
    * NumberRange validator if column if of type Integer, Float or Decimal and column info parameter has min or max arguments defined
    * DateRange validator if column is of type Date or DateTime and column info parameter has min or max arguments defined
    * TimeRange validator if column is of type Time and info parameter has min or max arguments defined
    * Unique validator if column has a unique index
    * Length validator for String/Unicode columns with max length
    * Optional validator for all nullable columns


Unique validator
----------------

WTForms-Alchemy automatically assigns unique validators for columns which have unique indexes defined. Unique validator raises ValidationError exception whenever a non-unique value for given column is assigned. Consider the following model/form definition. Notice how you need to define get_session() classmethod for your form. Unique validator uses this method for getting the appropriate SQLAlchemy session.
::


    engine = create_engine('sqlite:///:memory:')

    Base = declarative_base()

    Session = sessionmaker(bind=engine)
    session = Session()


    class User(Base):
        __tablename__ = 'user'

        id = sa.Column(sa.Integer, primary_key=True)
        name = sa.Column(sa.Unicode(100), nullable=False)
        email = sa.Column(
            sa.Unicode(255),
            nullable=False,
            unique=True
        )

    class UserForm(ModelForm):
        class Meta:
            model = User

        @classmethod
        def get_session():
            # this method should return sqlalchemy session
            return session


Here UserForm would behave the same as the following form:
::


    class UserForm(Form):
        name = TextField('Name', validators=[DataRequired(), Length(max=100)])
        email = TextField(
            'Email',
            validators=[
                DataRequired(),
                Length(max=255),
                Unique(User.email, get_session=lambda: session)
            ]
        )


If you are using Flask-SQLAlchemy or similar tool, which assigns session-bound query property to your declarative models, you don't need to define the get_session() method. Simply use:

::

    Unique(User.email)


Using unique validator with existing objects
--------------------------------------------

When editing an existing object, WTForms-Alchemy must know the object currently edited to avoid raising a ValidationError. Here how to proceed to inform WTForms-Alchemy of this case.
Example::

    obj = MyModel.query.get(1)
    form = MyForm(obj=obj)
    form.populate_obj(obj)
    form.validate()

WTForms-Alchemy will then understand to avoid the unique validation of the object with this same object.


Range validators
----------------

WTForms-Alchemy automatically assigns range validators based on column type and assigned column info min and max attributes.

In the following example we create a form for Event model where start_time can't be set in the past.

::

    class Event(Base):
        __tablename__ = 'event'

        id = sa.Column(sa.Integer, primary_key=True)
        name = sa.Column(sa.Unicode(255))
        start_time = sa.Column(sa.DateTime, info={'min': datetime.now()})


    class EventForm(ModelForm):
        class Meta:
            model = Event



Additional field validators
---------------------------

Example::

    from wtforms.validators import Email

    class User(Base):
        __tablename__ = 'user'

        name = sa.Column(sa.Unicode(100), primary_key=True, nullable=False)
        email = sa.Column(
            sa.Unicode(255),
            nullable=False,
            info={'validators': Email()}
        )

    class UserForm(ModelForm):
        class Meta:
            model = User

Now the 'email' field of UserForm would have Email validator.


Overriding default validators
-----------------------------

Sometimes you may want to override what class WTForms-Alchemy uses for email, number_range, length etc. validations.
For all automatically assigned validators WTForms-Alchemy provides configuration options to override the default validator.

In the following example we set a custom Email validator for User class.

::


    from sqlalchemy_utils import EmailType
    from wtforms_components import Email


    class User(Base):
        __tablename__ = 'user'

        name = sa.Column(sa.Unicode(100), primary_key=True, nullable=False)
        email = sa.Column(
            EmailType,
            nullable=False,
        )

    class MyEmailValidator(Email):
        def __init__(self, message='My custom email error message'):
            Email.__init__(self, message=message)


    class UserForm(ModelForm):
        class Meta:
            model = User
            email_validator = MyEmailValidator


If you don't wish to subclass you can simply use functions / lambdas:

::


    def email():
        return Email(message='My custom email error message')


    class UserForm(ModelForm):
        class Meta:
            model = User
            email_validator = email


You can also override validators that take multiple arguments this way:

::


    def length(min=None, max=None):
        return Length(min=min, max=max, message='Wrong length')


    class UserForm(ModelForm):
        class Meta:
            model = User
            length_validator = length


Here is the full list of configuration options you can use to override default validators:

* email_validator

* length_validator

* unique_validator

* number_range_validator

* date_range_validator

* time_range_validator

* optional_validator


Disabling validators
--------------------

You can disable certain validators by assigning them as `None`. Let's say you want to disable nullable columns having `Optional` validator. This can be achieved as follows::


    class UserForm(ModelForm):
        class Meta:
            model = User
            optional_validator = None