def __define_virtuals(self): field_names = [field.name for field in self.fields] for name in dir(self): if not name.startswith("_"): obj = self.__getattribute__(name) if isinstance(obj, virtualfield): if obj.field_name in field_names: raise RuntimeError( 'virtualfield or fieldmethod cannot have same ' + 'name as an existent field!') if isinstance(obj, fieldmethod): #f = Field.Method(obj.field_name, lambda row, obj=obj, # self=self: obj.f(self, row)) f = Field.Method(obj.field_name, _virtualwrap(self, obj)) else: #f = Field.Virtual(obj.field_name, lambda row, obj=obj, # self=self: obj.f(self, row)) f = Field.Virtual(obj.field_name, _virtualwrap(self, obj)) self.fields.append(f)
def __new__( cls, db, action, # 'define_table' or 'Table' prefix=None, name=None, auto_pk=None, common_hook=None, ): tname = name or cls.__name__ fields = list() hooks = dict() table_methods = dict( ) # https://github.com/web2py/pydal/blob/232e841765ee97ac6f7af45be794d46432085c4d/pydal/objects.py#L340 kwargs = dict() need_pk = False for name, attr in cls.__dict__.items(): if name.startswith('__'): continue # hooks if name in HOOKS: hooks[name] = attr # Field.Virtual elif isinstance(attr, property): fields.append(DalField.Virtual(name, attr.fget)) # table method elif isinstance(attr, classmethod): table_methods[name] = attr.__func__ # just Field elif isinstance(attr, Field): attr.name = name if not need_pk and auto_pk and name == 'id' and attr.args and attr.args[ 0] != 'id': need_pk = True fields.append(DalField(name, *attr.args, **attr.kwargs)) # Field.Method elif callable(attr): fields.append(DalField.Method(name, attr)) else: kwargs[name] = attr for sign in cls.__bases__: if sign is not Table: fields.append(get_signature(db, sign)) args = [tname] + fields if action == 'Table': args.insert(0, db) action = getattr(db, action) # auto_pk if need_pk and kwargs.get('primarykey') is None: kwargs['primarykey'] = ['id'] # rname prefix if prefix: kwargs['rname'] = f"{prefix}{tname}" # define table tbl = action(*args, **kwargs) or db[tname] # set hooks for hook_name, hook in hooks.items(): tbl[f"_{hook_name}"].append(hook) if common_hook: for hook_name in HOOKS: tbl[f"_{hook_name}"].append( lambda *args, hook_name=hook_name, **kw: common_hook( tbl, hook_name, *args, **kw)) # set table methods for meth_name, meth in table_methods.items(): tbl.add_method.register(meth_name)(meth) return tbl