Esempio n. 1
0
    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
Esempio n. 2
0
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()
            }
Esempio n. 3
0
    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
Esempio n. 4
0
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
Esempio n. 5
0
 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..."
Esempio n. 6
0
    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
Esempio n. 7
0
    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