def __repr__(self): from model.functions import get_name rel_type = type(self).name owner = get_name(self.owner.model) field = self.owner.field_name inverse_field = self.inverse.field_name inverse = get_name(self.inverse.model) if self.inverse_relation: return "<bidirectional {} between {}.{} and {}.{}>".format(rel_type, owner, field, inverse, inverse_field) else: return "<unidirectional {} between {}.{} and {}.{}>".format(rel_type, owner, field, inverse, inverse_field)
def load(self, module): """Load a specific module. This method: Get the Model class defined in the module Try to find the corresponding repository Write this dclass in the model's bundle Return the class """ name = Rule.module_name(module) bundle_name = Rule.bundle_name(module) bundle = self.server.bundles[bundle_name] class_name = name.capitalize() mod_class = getattr(module, class_name) mod_class.bundle = bundle mod_name = get_name(mod_class) # Try to find the corresponding repository if mod_name in bundle.repositories: rep_class = bundle.repositories[mod_name] print("Found the repository", rep_class) else: rep_class = Repository print("Create a new repository") repository = rep_class(self.data_connector, mod_class) mod_class._repository = repository # Write the class in the bundles bundle.models[mod_name] = mod_class # Record the new bundle in the data connector self.data_connector.repository_manager.record_model(mod_class) return mod_class
def find_relation(self): """Find and return the relation. First we select the type of this field. Next we try to find an inverse relation field in the foreign model. With them, we can create one or two relations (bidirectional relations are two relations bound together). For instance, if the 'self' field type is a 'has_one' and the foreign model has a 'has_many' pointing to the original model, then we create a 'One2ManyRelation' between 'self' and the foreign model and an inverse relation ('Many2OneRelation') between the foreign model and 'self'. """ from model.functions import get_fields, get_name nb_self = self.nb_foreign_models if isinstance(self.foreign_model, str): self.foreign_model = self.model._repository.get_model( self.foreign_model) # Now we try to find the inverse field foreign_fields = get_fields(self.foreign_model, register=False) foreign_fields = [field for field in foreign_fields if \ field is not self] foreign_field = None for field in foreign_fields: if isinstance(field, Related) and (get_name( self.model) == field.foreign_model or isinstance( field.foreign_model, type(self.model))): foreign_field = field foreign_field.foreign_model = self.model break if foreign_field is None: raise ValueError("the foreign field for the {}.{} field " \ "cannot be found in {}".format(self.model, self.field_name, self.foreign_model)) nb_foreign = foreign_field.nb_foreign_models cls_relation = None cls_inverse_relation = None if nb_self == 0: return None elif nb_self == -1: if nb_foreign == 1: cls_relation = Many2OneRelation cls_inverse_relation = One2ManyRelation elif nb_foreign == -1: # many2many pass else: cls_relation = Many2OneRelation else: if nb_foreign == 1: # one2one pass elif nb_foreign == -1: cls_relation = One2ManyRelation cls_inverse_relation = Many2OneRelation else: # one2one pass relation = cls_relation(self, foreign_field) if cls_inverse_relation: inverse_relation = cls_inverse_relation(foreign_field, self) inverse_relation.inverse_relation = relation relation.inverse_relation = inverse_relation return relation