fixing form handling for relationships

This commit is contained in:
evilchili
2024-02-04 11:40:30 -08:00
parent 32d9c42847
commit 669c9b46d6
13 changed files with 206 additions and 122 deletions
+2 -34
View File
@@ -8,6 +8,7 @@ from slugify import slugify
from sqlalchemy import Column
from sqlalchemy import String
def genslug():
return nanoid.generate(human_alphabet[2:], 5)
@@ -37,38 +38,5 @@ class IterableMixin:
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, SlugMixin]
Bases = [BaseObject, IterableMixin, SlugMixin]
+4 -4
View File
@@ -8,9 +8,9 @@ from sqlalchemy.exc import IntegrityError
# move this to json or whatever
data = {
'Ancestry': [
{'id': 1, 'name': 'human'},
{'id': 2, 'name': 'dragonborn'},
{'id': 3, 'name': 'tiefling'},
{'name': 'human'},
{'name': 'dragonborn'},
{'name': 'tiefling'},
],
'Character': [
{'id': 1, 'name': 'Sabetha', 'ancestry': 'tiefling', 'level': 10, 'str': 10, 'dex': 10, 'con': 10, 'int': 10, 'wis': 10, 'cha': 10},
@@ -31,9 +31,9 @@ def bootstrap():
try:
with db.transaction():
db.session.add(obj)
logging.info(f"Created {table} {obj}")
except IntegrityError as e:
if 'UNIQUE constraint failed' in str(e):
logging.info(f"Skipping existing {table} {obj}")
continue
raise
logging.info(f"Created {table} {obj}")
+4 -2
View File
@@ -11,8 +11,10 @@ from ttfrog.db.base import Bases
class Ancestry(*Bases):
__tablename__ = "ancestry"
id = Column(Integer, primary_key=True, autoincrement=True)
name = Column(String, index=True, unique=True)
name = Column(String, primary_key=True, unique=True)
def __repr__(self):
return str(self.name)
class Character(*Bases):