tabletop-frog/ttfrog/db/base.py

54 lines
1.8 KiB
Python
Raw Normal View History

2024-01-31 22:39:54 -08:00
from pyramid_sqlalchemy import BaseObject
from wtforms import validators
class IterableMixin:
"""
Allows for iterating over Model objects' column names and values
"""
def __iter__(self):
values = vars(self)
for attr in self.__mapper__.columns.keys():
if attr in values:
yield attr, values[attr]
def __repr__(self):
return f"{self.__class__.__name__}: {str(dict(self))}"
class FormValidatorMixin:
"""
Add form validation capabilities using the .info attributes of columns.
"""
# column.info could contain any of these keywords. define the list of validators that should apply
# whenever we encounter one such keyword.
_validators_by_keyword = {
'min': [validators.NumberRange],
'max': [validators.NumberRange],
}
@classmethod
def validate(cls, form):
for name, column in cls.__mapper__.columns.items():
if name not in form._fields:
continue
# step through the info keywords and create a deduped list of validator classes that
# should apply to this form field. This prevents adding unnecessary copies of the same
# validator when two or more keywords map to the same one.
extras = set()
for key in column.info.keys():
for val in cls._validators_by_keyword.get(key, []):
extras.add(val)
# Add an instance of every unique validator for this column to the associated form field.
form._fields[name].validators.extend([v(**column.info) for v in extras])
# return the results of the form validation,.
return form.validate()
# class Table(*Bases):
Bases = [BaseObject, IterableMixin, FormValidatorMixin]