def dummy_class_to_ressource(self, klass): module = klass.__module__.split(".")[0:-1] module = ".".join(module + ["resources", klass.__name__ + "Resource"]) try: # Try to import the class import_class(module) return module except ImportError: return None
def dummy_class_to_ressource(self, klass): module = klass.__module__.split(".") # Remove last path part if need if module[-1] == 'models': module = module[0:-1] # Build the resource path module = ".".join(module + ["resources", klass.__name__ + "Resource"]) try: # Try to import the class import_class(module) return module except ImportError: return None
def default_rules(topic): # ModelRules is a singleton that record every model rules rules = ModelRules() # We cant import this early to avoid bi-directional dependancies from app.detective.utils import import_class # Get all registered models models = Topic.objects.get(module=topic).get_models() # Set "is_searchable" to true on every model with a name for model in models: # If the current model has a name if "name" in rules.model(model).field_names: field_names = rules.model(model).field_names # Count the fields len fields_len = len(field_names) # Put the highest priority to that name rules.model(model).field('name').add(priority=fields_len) # This model isn't searchable else: rules.model(model).add(is_searchable=False) # Check now that each "Relationship" # match with a searchable model for model in models: for field in model._meta.fields: # Find related model for relation if hasattr(field, "target_model"): target_model = field.target_model # Load class path if type(target_model) is str: target_model = import_class(target_model) # It's a searchable field ! modelRules = rules.model(target_model).all() # Set it into the rules rules.model(model).field(field.name).add(is_searchable=modelRules["is_searchable"]) rules.model(model).field(field.name).add(is_editable=modelRules["is_editable"]) return rules
def get_to_many_field(self, field, full=False): if type(field.target_model) == str: target_model = import_class(field.target_model) else: target_model = field.target_model resource = self.dummy_class_to_ressource(target_model) # Do not create a relationship with an empty resource (not resolved) if resource: return fields.ToManyField(resource, field.name, full=full, null=True, use_in='detail') else: return None
def dummy_model_to_ressource(model, get=False): from app.detective.utils import import_class path = model.__module__.split(".") # Remove last path part if need if path[-1] == 'models': path = path[0:-1] # Build the resource path path = ".".join(path + ["resources", model.__name__ + "Resource"]) try: # Try to import the class resource = import_class(path) return resource if get else path except ImportError: return None
def default_rules(self, topic): # ModelRules is a singleton that record every model rules rules = ModelRules() # We cant import this early to avoid bi-directional dependancies from app.detective.utils import import_class models = self.topic_models(topic) treated_models = [] # Set "is_searchable" to true on every model with a name for model in models: # If the current model has a name if "name" in rules.model(model).field_names: field_names = rules.model(model).field_names # Count the fields len fields_len = len(field_names) # Put the highest priority to that name rules.model(model).field("name").add(priority=fields_len) rules.model(model).add(is_searchable=True) # This model isn't searchable else: rules.model(model).add(is_searchable=False) # since we use a generator for topics models we need to convert it # to a list to perform a 2nd loop. treated_models.append(model) # we need to pass a first time on every models to have the proper rules # and a second for their RelationShip fields for model in treated_models: # Check now that each "Relationship" # match with a searchable model for field in model._meta.fields: # Find related model for relation if hasattr(field, "target_model"): target_model = field.target_model # Load class path if type(target_model) is str: target_model = import_class(target_model) # It's a searchable field ! modelRules = rules.model(target_model).all() # Set it into the rules rules.model(model).field(field.name).add(is_searchable=modelRules["is_searchable"]) # Entering relationship are not editable yet is_editable = ( (False if hasattr(target_model, field.name) else False) if field.direction == "in" and target_model is model else modelRules["is_editable"] ) rules.model(model).field(field.name).add(is_editable=is_editable) return rules
def default_rules(self, topic): # ModelRules is a singleton that record every model rules rules = ModelRules() # We cant import this early to avoid bi-directional dependancies from app.detective.utils import import_class models = self.topic_models(topic) treated_models = [] # Set "is_searchable" to true on every model with a name for model in models: # If the current model has a name if "name" in rules.model(model).field_names: field_names = rules.model(model).field_names # Count the fields len fields_len = len(field_names) # Put the highest priority to that name rules.model(model).field('name').add(priority=fields_len) rules.model(model).add(is_searchable=True) # This model isn't searchable else: rules.model(model).add(is_searchable=False) # since we use a generator for topics models we need to convert it # to a list to perform a 2nd loop. treated_models.append(model) # we need to pass a first time on every models to have the proper rules # and a second for their RelationShip fields for model in treated_models: # Check now that each "Relationship" # match with a searchable model for field in model._meta.fields: # Find related model for relation if hasattr(field, "target_model"): target_model = field.target_model # Load class path if type(target_model) is str: target_model = import_class(target_model) # It's a searchable field ! modelRules = rules.model(target_model).all() # Set it into the rules rules.model(model).field(field.name).add( is_searchable=modelRules["is_searchable"]) # Entering relationship are not editable yet is_editable = (False if hasattr(target_model, field.name) else False) \ if field.direction == 'in' and target_model is model else modelRules["is_editable"] rules.model(model).field( field.name).add(is_editable=is_editable) return rules
def get_relationships(self, request, **kwargs): # Extract node id from given node uri def node_id(uri) : return re.search(r'(\d+)$', uri).group(1) # Get the end of the given relationship def rel_from(rel, side): return node_id(rel.__dict__["_dic"][side]) # Is the given relation connected to the given uri def connected(rel, idx): return rel_from(rel, "end") == idx or rel_from(rel, "start") == idx self.method_check(request, allowed=['get']) self.throttle_check(request) pk = kwargs['pk'] node = connection.nodes.get(pk) # Only the relationships for a given field if "field" in kwargs: field = self.get_model_fields(kwargs["field"]) # Unkown type if field is None: raise Http404("Unkown relationship field.") reltype = getattr(field, "rel_type", None) # Not a relationship if reltype is None: raise Exception("The given field is not a relationship.") rels = node.relationships.all(types=[reltype]) # We want to filter the relationships with an other node if "end" in kwargs: end = kwargs["end"] # Then filter the relations ids = [ rel.id for rel in rels if connected(rel, end) ] if len(ids): # Show additional field following the model's rules rules = request.current_topic.get_rules() # Model that manages properties though = rules.model( self.get_model() ).field(kwargs["field"]).get("through") if though: # Get the properties for this relationship try: properties = though.objects.get(_relationship=ids[0]) except though.DoesNotExist: endnodes = [ int(pk), int(end) ] # We ask for relationship properties return self.create_response(request, { "_relationship": ids[0], "_endnodes": endnodes }) else: # Get the module for this model module = self.dummy_class_to_ressource(though) # Instanciate the resource resource = import_class(module)() # Create a bundle with this resource bundle = resource.build_bundle(obj=properties, request=request) bundle = resource.full_dehydrate(bundle, for_list=True) # We ask for relationship properties return resource.create_response(request, bundle) else: # No relationship return self.create_response(request, { "_relationship": None }) # All relationship else: rels = node.relationships.all() # Only returns IDS ids = [ rel.id for rel in rels ] return self.create_response(request, ids)