Beispiel #1
0
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)
Beispiel #2
0
    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)