Created
November 12, 2014 11:09
-
-
Save moschlar/c56c3382292f83b882da to your computer and use it in GitHub Desktop.
Minimal working example to demonstrate issue TurboGears/sprox#4
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
'''Minimal working example to demonstrate issue TurboGears/sprox#4 | |
Summary: | |
If the "many" side of a sqlalchemy relationship is also a required field | |
in sprox, the MultipleSelectField gets a UnicodeString validator, which | |
simply converts the value to a string, regardless of its type (in this | |
example, it leads to the repr string being used as the value). For | |
determining the selected options of the select field, the in operator | |
is then used on whatever string got generated first, leading to awkwardly | |
wrong selected values. | |
''' | |
from sqlalchemy import Column, Integer, ForeignKey, create_engine | |
from sqlalchemy.orm import relationship, backref, sessionmaker | |
from sqlalchemy.ext.declarative import declarative_base | |
from sprox.formbase import EditableForm | |
from sprox.widgets.tw2widgets.widgets import PropertyMultipleSelectField | |
#----------------------------------------------------------------------------- | |
# tw2 middleware mocking | |
import tw2.core.core | |
import tw2.core.middleware as tmw | |
_request_local = {'middleware': tmw.make_middleware(None)} | |
tw2.core.core.request_local = lambda: _request_local | |
from tw2.core.core import request_local | |
#----------------------------------------------------------------------------- | |
Base = declarative_base() | |
class Parent(Base): | |
__tablename__ = 'parents' | |
id = Column(Integer, primary_key=True) | |
class Child(Base): | |
__tablename__ = 'children' | |
id = Column(Integer, primary_key=True) | |
parent_id = Column(Integer, ForeignKey(Parent.id)) | |
parent = relationship(Parent, backref=backref('children')) | |
def __repr__(self): | |
return '<Child(id=%r)>' % (self.id) | |
class MyPropertyMultipleSelectField(PropertyMultipleSelectField): | |
'''This subclass is just for "inspection" purposes''' | |
def prepare(self): | |
'''Note how self.value changes''' | |
print self.validator, self.value | |
result = super(MyPropertyMultipleSelectField, self).prepare() | |
print self.validator, self.value | |
return result | |
class EditParentForm(EditableForm): | |
__model__ = Parent | |
__require_fields__ = ['children'] | |
__field_widget_types__ = {'children': MyPropertyMultipleSelectField} | |
if __name__ == '__main__': | |
engine = create_engine('sqlite:///:memory:', echo=False) | |
Base.metadata.create_all(engine) | |
Session = sessionmaker(bind=engine) | |
session = Session() | |
parent = Parent() | |
session.add(parent) | |
children = [Child(id=1), Child(id=3), Child(id=5), Child(id=13, parent=parent)] | |
session.add_all(children) | |
session.commit() | |
value = session.query(Parent).first() | |
print [c.id for c in value.children] | |
edit_parent_form = EditParentForm(session) | |
widgets = edit_parent_form._do_get_field_widgets(['children']) | |
print widgets['children'], widgets['children'].validator | |
print edit_parent_form.display(value=value) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment