def dehydrate(self, bundle): from app.detective import register # Get the model's rules manager rulesManager = register.topics_rules() # Get all registered models models = get_registered_models() # Filter model to the one under app.detective.topics bundle.data["models"] = [] # Create a thumbnail for this topic try: thumbnailer = get_thumbnailer(bundle.obj.background) thumbnailSmall = thumbnailer.get_thumbnail({'size': (60, 60), 'crop': True}) thumbnailMedium = thumbnailer.get_thumbnail({'size': (300, 200), 'crop': True}) bundle.data['thumbnail'] = { 'small' : thumbnailSmall.url, 'medium': thumbnailMedium.url } # No image available except InvalidImageFormatError: bundle.data['thumbnail'] = None for m in bundle.obj.get_models(): model = { 'name': m.__name__, 'verbose_name': m._meta.verbose_name, 'verbose_name_plural': m._meta.verbose_name_plural, 'is_searchable': rulesManager.model(m).all().get("is_searchable", False) } bundle.data["models"].append(model) return bundle
def iterate_model_fields(model, order_by='name'): from app.detective import register from django.db.models.fields import FieldDoesNotExist models_rules = register.topics_rules().model(model) if hasattr(model, '__fields_order__'): _len = len(model._meta.fields) model_fields = sorted( model._meta.fields, key=lambda x: model.__fields_order__.index(x.name) if x.name in model.__fields_order__ else _len) else: model_fields = sorted(model._meta.fields, key=lambda el: getattr(el, order_by)) for f in model_fields: # Ignores field terminating by + or begining by _ if not f.name.endswith("+") and not f.name.endswith( "_set") and not f.name.startswith("_"): try: # Get the rules related to this model field_rules = models_rules.field(f.name).all() except FieldDoesNotExist: # No rules field_rules = [] field_type = f.get_internal_type() # Find related model for relation if field_type.lower() == "relationship": # We received a model as a string if type(f.target_model) is str: # Extract parts of the module path module_path = f.target_model.split(".") # Import models as a module module = __import__(".".join(module_path[0:-1]), fromlist=["class"]) # Import the target_model from the models module target_model = getattr(module, module_path[-1], {__name__: None}) else: target_model = f.target_model related_model = target_model.__name__ else: related_model = None verbose_name = getattr(f, "verbose_name", None) if verbose_name is None: # Use the name as verbose_name fallback verbose_name = pretty_name(f.name).lower() yield { 'name': f.name, 'type': field_type, 'direction': getattr(f, "direction", ""), 'rel_type': getattr(f, "rel_type", ""), 'help_text': getattr(f, "help_text", ""), 'verbose_name': verbose_name, 'related_model': related_model, 'model': model.__name__, 'rules': field_rules.copy() }
def alter_detail_data_to_serialize(self, request, bundle): # Show additional field following the model's rules rules = register.topics_rules().model(self.get_model()).all() # All additional relationships for key in rules: # Filter rules to keep only Neomatch if isinstance(rules[key], Neomatch): bundle.data[key] = rules[key].query(bundle.obj.id) return bundle
def get_model_fields(model, order_by='name'): from app.detective import register from django.db.models.fields import FieldDoesNotExist fields = [] models_rules = register.topics_rules().model(model) # Create field object for f in model._meta.fields: # Ignores field terminating by + or begining by _ if not f.name.endswith("+") and not f.name.endswith("_set") and not f.name.startswith("_"): # Find related model for relation if f.get_internal_type().lower() == "relationship": # We received a model as a string if type(f.target_model) is str: # Extract parts of the module path module_path = f.target_model.split(".") # Import models as a module module = __import__( ".".join(module_path[0:-1]), fromlist=["class"]) # Import the target_model from the models module target_model = getattr(module, module_path[-1], {__name__: None}) else: target_model = f.target_model related_model = target_model.__name__ else: related_model = None try: # Get the rules related to this model field_rules = models_rules.field(f.name).all() except FieldDoesNotExist: # No rules field_rules = [] verbose_name = getattr(f, "verbose_name", None) if verbose_name is None: # Use the name as verbose_name fallback verbose_name = pretty_name(f.name) field = { 'name' : f.name, 'type' : f.get_internal_type(), 'direction' : getattr(f, "direction", ""), 'rel_type' : getattr(f, "rel_type", ""), 'help_text' : getattr(f, "help_text", ""), 'verbose_name' : verbose_name, 'related_model': related_model, 'model' : model.__name__, 'rules' : field_rules } fields.append(field) get_key=lambda el: el[order_by] fields = sorted(fields, key=get_key) return fields
def search_placeholder(self, max_suggestion=5): from app.detective import register # Get the model's rules manager rulesManager = register.topics_rules() # List of searchable models searchableModels = [] # Filter searchable models for model in self.get_models(): if rulesManager.model(model).all().get("is_searchable", False): searchableModels.append(model) names = [ sm._meta.verbose_name_plural.lower() for sm in searchableModels ] random.shuffle(names) # No more than X names if len(names) > max_suggestion: names = names[0:max_suggestion] if len(names): return "Search for " + ", ".join(names[0:-1]) + " and " + names[-1] else: return "Search..."
def dehydrate(self, bundle): # Show additional field following the model's rules rules = register.topics_rules().model( self.get_model() ) # Get the output transformation for this model transform = rules.get("transform") # This is just a string # For complex formating use http://docs.python.org/2/library/string.html#formatspec if type(transform) is str: transform = transform.format(**bundle.data) # We can also receive a function elif callable(transform): transform = transform(bundle.data) bundle.data["_transform"] = transform or getattr(bundle.data, 'name', None) # Control that every relationship fields are list # and that we didn't send hidden field for field in bundle.data: # Find the model's field modelField = getattr(bundle.obj, field, False) # The current field is a relationship if modelField and hasattr(modelField, "_rel"): # Wrong type given, relationship field must ouput a list if type(bundle.data[field]) is not list: # We remove the field from the ouput bundle.data[field] = [] # The field is a list of literal values elif type(modelField) in (list, tuple): # For tuple serialization bundle.data[field] = modelField # Get the output transformation for this field transform = rules.field(field).get("transform") # This is just a string # For complex formating use http://docs.python.org/2/library/string.html#formatspec if type(transform) is str: bundle.data[field] = transform.format(**bundle.data) # We can also receive a function elif callable(transform): bundle.data[field] = transform(bundle.data, field) return bundle
def summary_forms(self, bundle, request): available_resources = {} # Get the model's rules manager rulesManager = topics_rules() # Fetch every registered model # to print out its rules for model in self.topic.get_models(): name = model.__name__.lower() rules = rulesManager.model(model).all() fields = utils.get_model_fields(model) verbose_name = getattr(model._meta, "verbose_name", name).title() verbose_name_plural = getattr(model._meta, "verbose_name_plural", verbose_name + "s").title() for key in rules: # Filter rules to keep only Neomatch if isinstance(rules[key], Neomatch): fields.append({ "name" : key, "type" : "ExtendedRelationship", "verbose_name" : rules[key].title, "rules" : {}, "related_model": rules[key].target_model.__name__ }) available_resources[name] = { 'description' : getattr(model, "_description", None), 'topic' : getattr(model, "_topic", self.topic.slug) or self.topic.slug, 'model' : getattr(model, "__name_", ""), 'verbose_name' : verbose_name, 'verbose_name_plural' : verbose_name_plural, 'name' : name, 'fields' : fields, 'rules' : rules } return available_resources