def required_widget(prop): """Returns bool Returns True if the widget corresponding to the given prop should be required """ is_nullable = lambda prop: sum([c.nullable for c in getattr(prop, 'columns', [])]) if not is_relation(prop): if not is_nullable(prop): return True return False if not is_manytoone(prop) and not is_onetoone(prop): return False localname = compat.local_name(prop) # If the local field is required, the relation should be required pkey = dict([(p.key, is_nullable(p)) for p in prop.parent.iterate_properties]) return not pkey.get(localname, True)
def post_define(cls): if not getattr(cls, 'entity', None) and getattr(cls.parent, 'entity', None): cls.entity = cls.parent.entity if getattr(cls, 'entity', None) and not getattr(cls, '_auto_widgets', False): cls._auto_widgets = True fkey = dict((compat.local_name(p), p) for p in sa.orm.class_mapper(cls.entity).iterate_properties if is_manytoone(p) or is_onetoone(p)) new_children = [] used_children = set() orig_children = getattr(cls.child, 'children', []) mapper = sa.orm.class_mapper(cls.entity) properties = mapper._props.values() localname_from_relationname = dict((p.key, compat.local_name(p)) for p in mapper.iterate_properties if is_manytoone(p) or is_onetoone(p)) localname_creation_order = dict((p.key, p._creation_order) for p in mapper.iterate_properties if not is_relation(p)) properties.sort(sort_properties(localname_from_relationname, localname_creation_order)) reverse_property_name = getattr(cls, 'reverse_property_name', None) for prop in properties: # Swap ids and objs if fkey.get(prop.key): continue if prop.key == reverse_property_name: # Avoid circular loop for the one to one relation continue widget_name = prop.key if isinstance(prop, sa.orm.RelationshipProperty): widget_name = compat.local_name(prop) matches = [w for w in orig_children if w.key == widget_name] widget = len(matches) and matches[0] or None if widget: if not issubclass(widget, NoWidget): new_children.append(widget) used_children.add(widget_name) else: new_widget = cls.policy.factory(prop) if new_widget: new_children.append(new_widget) edit_link = getattr(cls.entity, 'tws_edit_link', None) if cls.policy.add_edit_link and edit_link: new_children += [DbLinkField('edit', text='edit', entity=cls.entity, link=edit_link)] def child_filter(w): return w.key not in used_children and \ w.key not in [W.key for W in new_children] new_children.extend(filter(child_filter, orig_children)) cls.required_children = [] if getattr(cls, 'required_on_parent', False): for c in new_children: if c.validator and c.validator.required: cls.required_children += [c] c.validator.required = False cls.child = cls.child(children=new_children, entity=cls.entity)