rom/columns.py
def _on_delete(ent):
    '''
    This function handles all on_delete semantics defined on OneToMany columns.

    This function only exists because 'cascade' is *very* hard to get right.
    '''
    seen_d = set([ent._pk])
    to_delete = [ent]
    seen_s = set()
    to_save = []

    def _set_default(ent, attr, de=NULL):
        pk = ent._pk
        if pk in seen_d:
            # going to be deleted, don't need to modify
            return

        col = ent.__class__._columns[attr]
        de = de if de is not NULL else col._default
        if de in (None, NULL):
            setattr(ent, attr, None)
        elif callable(col._default):
            setattr(ent, attr, col._default())
        else:
            setattr(ent, attr, col._default)

        if pk not in seen_s:
            seen_s.add(pk)
            to_save.append(ent)

    for self in to_delete:
        for tbl, attr, action in MODELS_REFERENCED.get(self._namespace, ()):
            if action == 'no action':
                continue

            refs = MODELS[tbl].get_by(**{attr: self.id})
            if not refs:
                continue

            if action == 'restrict':
                # raise the exception here for a better traceback
                raise _restrict(self, attr, refs)
            elif action == 'set null':
                for ref in refs:
                    _set_default(ref, attr, None)
                continue
            elif action == 'set default':
                for ref in refs:
                    _set_default(ref, attr)
                continue

            # otherwise col._on_delete == 'cascade'
            for ent in (refs if isinstance(refs, list) else [refs]):
                if ent._pk not in seen_d:
                    seen_d.add(ent._pk)
                    to_delete.append(ent)

    # If we got here, then to_delete includes all items to delete. Let's delete
    # them!
    for self in to_delete:
        self.delete(skip_on_delete_i_really_mean_it=SKIP_ON_DELETE)
    for self in to_save:
        # Careful not to resurrect deleted entities
        if self._pk not in seen_d:
            self.save()
def _on_delete(ent):
    '''
    This function handles all on_delete semantics defined on OneToMany columns.

    This function only exists because 'cascade' is *very* hard to get right.
    '''
    seen_d = set([ent._pk])
    to_delete = [ent]
    seen_s = set()
    to_save = []

    def _set_default(ent, attr, de=NULL):
        pk = ent._pk
        if pk in seen_d:
            # going to be deleted, don't need to modify
            return

        col = ent.__class__._columns[attr]
        de = de if de is not NULL else col._default
        if de in (None, NULL):
            setattr(ent, attr, None)
        elif callable(col._default):
            setattr(ent, attr, col._default())
        else:
            setattr(ent, attr, col._default)

        if pk not in seen_s:
            seen_s.add(pk)
            to_save.append(ent)

    for self in to_delete:
        for tbl, attr, action in MODELS_REFERENCED.get(self._namespace, ()):
            if action == 'no action':
                continue

            refs = MODELS[tbl].get_by(**{attr: self.id})
            if not refs:
                continue

            if action == 'restrict':
                # raise the exception here for a better traceback
                raise _restrict(self, attr, refs)
            elif action == 'set null':
                for ref in refs:
                    _set_default(ref, attr, None)
                continue
            elif action == 'set default':
                for ref in refs:
                    _set_default(ref, attr)
                continue

            # otherwise col._on_delete == 'cascade'
            for ent in (refs if isinstance(refs, list) else [refs]):
                if ent._pk not in seen_d:
                    seen_d.add(ent._pk)
                    to_delete.append(ent)

    # If we got here, then to_delete includes all items to delete. Let's delete
    # them!
    for self in to_delete:
        self.delete(skip_on_delete_i_really_mean_it=SKIP_ON_DELETE)
    for self in to_save:
        # Careful not to resurrect deleted entities
        if self._pk not in seen_d:
            self.save()
def _on_delete ( ent ) : seen_d = set ( [ ent . _pk ] ) to_delete = [ ent ] seen_s = set ( ) to_save = [ ] def _set_default ( ent , attr , de = NULL ) : pk = ent . _pk if pk in seen_d : # going to be deleted, don't need to modify return col = ent . __class__ . _columns [ attr ] de = de if de is not NULL else col . _default if de in ( None , NULL ) : setattr ( ent , attr , None ) elif callable ( col . _default ) : setattr ( ent , attr , col . _default ( ) ) else : setattr ( ent , attr , col . _default ) if pk not in seen_s : seen_s . add ( pk ) to_save . append ( ent ) for self in to_delete : for tbl , attr , action in MODELS_REFERENCED . get ( self . _namespace , ( ) ) : if action == 'no action' : continue refs = MODELS [ tbl ] . get_by ( * * { attr : self . id } ) if not refs : continue if action == 'restrict' : # raise the exception here for a better traceback raise _restrict ( self , attr , refs ) elif action == 'set null' : for ref in refs : _set_default ( ref , attr , None ) continue elif action == 'set default' : for ref in refs : _set_default ( ref , attr ) continue # otherwise col._on_delete == 'cascade' for ent in ( refs if isinstance ( refs , list ) else [ refs ] ) : if ent . _pk not in seen_d : seen_d . add ( ent . _pk ) to_delete . append ( ent ) # If we got here, then to_delete includes all items to delete. Let's delete # them! for self in to_delete : self . delete ( skip_on_delete_i_really_mean_it = SKIP_ON_DELETE ) for self in to_save : # Careful not to resurrect deleted entities if self . _pk not in seen_d : self . save ( )
This function handles all on_delete semantics defined on OneToMany columns.

    This function only exists because 'cascade' is *very* hard to get right.
This function handles all on_delete semantics defined on OneToMany columns .