예제 #1
0
    def filter(self, obj, library: Library = None):
        filter_func = None
        if library:
            filter_func = Obj.getattr(library.filters,
                                      self.filter_name,
                                      None,
                                      execute_callable=False)

        if not filter_func or not callable(filter_func):
            filter_func = Obj.getattr(defaultfilters,
                                      self.filter_name,
                                      None,
                                      execute_callable=False)

        if not filter_func or not callable(filter_func):
            filter_func = Obj.getattr(humanize,
                                      self.filter_name,
                                      None,
                                      execute_callable=False)

        if not filter_func or not callable(filter_func):
            raise ValueError('Invalid filter "%s"' % self.filter_name)

        if self.has_param():
            return filter_func(obj, self.filter_param)
        return filter_func(obj)
예제 #2
0
    def prep_select_optgroups(cls, the_list, opt_groups: list, value_attr,
                              display_attr, none_value_label):
        """
        Prep list to be use as a choice for the ChoiceField

            eg. sensor_choices = Lst.prep_select_optgroups(sensors, ['facility.name', 'zone.name'],
                                               'id', 'sensor_name', _('Unassigned Sensors'))

        :param the_list: ValueQuerySet, QuerySet or list
        :param opt_groups: the group column/attr name or index
        :param value_attr: the option value
        :param display_attr: the option display text
        :return:
        """
        groups = Lst.tuple_multi_group_by(the_list, none_value_label,
                                          opt_groups)

        if groups:
            result = []
            for tp, arr in groups.items():
                og_header = ' > '.join(tp)
                og_list = []
                for row in arr:
                    og_list.append((
                        Obj.getattr(row, value_attr),
                        Obj.getattr(row, display_attr),
                    ))
                result.append((
                    og_header,
                    tuple(og_list),
                ))
            return tuple(result)

        return groups
예제 #3
0
    def stage_audit_dict(cls, form):
        """
        Call the model default 'get_audit_dict()' function to prepare for the audit stage data.

        :type form: Form|ModelForm
        :param form:
        """
        instance = Obj.getattr(form, 'instance', None)
        if instance and instance.pk and Obj.has_func(instance, 'get_audit_dict'):
            instance._staged_data_point = instance.get_audit_dict()
예제 #4
0
def get_display(obj, attr_name):
    try:
        display_name = 'get_%s_display' % attr_name
        result = Obj.getattr(obj, display_name, None)

        if result is None:
            result = Obj.getattr(obj, attr_name, None)

        return result
    except:
        return None
예제 #5
0
    def diff(cls, old_dict: dict, new_dict: dict, excludes=None):
        """
        Compare two diff

        :param old_dict:
        :param new_dict:
        :param excludes:
        :return:
        """
        try:
            from django_lazifier2.utils.builtin_types.obj import Obj
        except ImportError:
            Obj = sys.modules[__package__ + '.Obj']

        if not isinstance(old_dict, dict):
            old_dict = Obj.get_dict(old_dict) or OrderedDict()

        if not isinstance(new_dict, dict):
            new_dict = Obj.get_dict(new_dict) or OrderedDict()

        result = OrderedDict()

        if not old_dict:
            for k, v in new_dict.items():
                if excludes is None or k not in excludes:
                    result[k + '_new'] = v
            return result

        for k, v in old_dict.items():
            if excludes is None or k not in excludes:

                if isinstance(v, dict):
                    result[k] = Dct.diff(v,
                                         new_dict.get(k, {}),
                                         excludes=excludes)
                    continue

                if k not in new_dict:
                    result[k + '_removed'] = v
                elif v != new_dict[k]:
                    result[k + '_old'] = v
                    result[k + '_new'] = new_dict[k]

        for k, v in new_dict.items():
            if excludes is None or k not in excludes:
                if k not in old_dict:
                    result[k + '_added'] = v

        return result
예제 #6
0
    def get_display_name(cls, model: Model, field_name, default_value=None):
        field_key = Obj.getattr(model, field_name)
        if field_key is None:
            return default_value
        field = model._meta.get_field(field_name)
        choices = Obj.getattr(field, 'choices')

        if choices is None:
            return default_value

        for k, v in choices:
            if k == field_key:
                return v

        return default_value
예제 #7
0
 def default(self, o):
     try:
         if isinstance(o, ValuesQuerySet) or isinstance(o, QuerySet):
             return [x for x in o]
         elif isinstance(o, JsonSerializer):
             return o.get_json_dict()
         elif isinstance(o, Model):
             return Obj.get_dict(o)
         elif isinstance(o, RawJsonString):
             placeholder = '[$RawJson-%s]' % uuid.uuid4()
             self.__raw_json_replacement[placeholder] = o.get_json()
             return placeholder
         elif isinstance(o, tzinfo):
             return str(o)
         elif isinstance(o, Decimal):
             return float(o)
         elif isinstance(o, Enum):
             return o.value
         elif isinstance(o, Promise):
             # translation proxy
             return str(o)
         elif isinstance(o, FieldFile):
             return o.name
         elif isinstance(o, bytes):
             return o.decode('utf-8', 'replace')
         elif PhoneNumber and isinstance(o, PhoneNumber):
             return o.as_national
     except Exception:
         pass
     return str(o)
예제 #8
0
    def get_dict(cls, model: models.Model, filter_list=None, exclude_list=None, verbose_key=False, related_fields: list=None,
                 related_names: list=None, key_maps: dict=None, get_display=False):
        """
        Extract the values from the instance of the model,
            if the fields is specified then remove other fields not in the list.

        :type related_fields: list|None
        :param model: The model
        :param filter_list:
        :param exclude_list:
        :param verbose_key: get the verbose of the field name, ie name would be _('Name')
        :param related_fields: merge the related model into the this result dict
        :param related_names: just get the name of the related model instead fo the entire model like related_fields
                                    field name or tuple (field_name, the_field_contain_the_name)
                                    eg. ['facility', 'zone', ('sensoralarmmap_set', 'alarm_alert_link.name')]
        :param key_maps: change the keys of the dict to diff value { 'old_key1': 'new_key1', ... }
        :param get_display: if a get_<name>_display exist, use that to get the verbose name
        :return:
        :rtype: dict
        """
        values = Obj.get_dict(model, filter_list=filter_list, exclude_list=exclude_list, verbose_key=verbose_key,
                              get_display=get_display)

        rel = Mdl.get_related_models(model, filter_list=filter_list, exclude_list=exclude_list, verbose_key=verbose_key,
                                    related_fields=related_fields)
        if rel:
            values.update(rel)

        names = Mdl.get_related_model_names(model, related_names)
        if names:
            values.update(names)

        values = Dct.key_maps(values, key_maps)

        return values
예제 #9
0
    def get_initial(cls, data, form: ModelForm, prefix=''):
        """
        Extract data from post to put it in form.initial

        :param data: dict|request.GET|request.POST|request.REQUEST
        :param form:
        :param prefix:
        :return:
        """
        if not data:
            return OrderedDict()

        data = Obj.get_dict(data)
        if prefix:
            # the Form put a dash between the prefix and the name
            # eg. field=name, prefix=alert  it becomes alert-name
            prefix += '-'

        result = OrderedDict()
        fields = list(form.base_fields.keys())

        for k, v in data.items():
            if not prefix or k.startswith(prefix):
                k = k.replace(prefix, '')

                if k in fields:
                    result[k] = v
        return result
예제 #10
0
    def group_by(cls, the_list, group, none_value_label='None', flat=False):
        """
        Group the list by the group specified.
            eg. Lst.group_by(seats, 'zone.name', 'do not belong to a zone')
                => { 'zone1': [seat1, seat2]
                     'zone2': [seat7, seat8]
                     'do not belong to a zone': [seat3, seat4, seat5]
                   }

        :param the_list:
        :param group: {str} name of the attribute, support dot notation group_by(persons, 'contact.phone')
        :param none_value_label: the value of the column specified is None then use this label as the key.
        :param flat: if true only take the last item for each group and put it in the result dict
        :rtype: dict
        """
        result = OrderedDict()
        for row in the_list:
            col_value = Obj.getattr(row, group, None)
            if col_value is None:
                col_value = none_value_label

            if not flat and col_value not in result:
                result[col_value] = []

            if flat:
                result[col_value] = row
            else:
                result[col_value].append(row)
        return result
예제 #11
0
    def get_related_model_names(cls, model: models.Model, related_names: list=None):
        """
        Extract name from foreign keys, foreign and m2m fields
                eg. { facility_id: 10, facility_name: 'Trenton', zone_id:, zone_name:, ... }

        :param model:
        :param related_names: either foreign key field name or a tuple (field_name, 'the-field-contain-the-name')
        :return:
        """
        if not related_names:
            return OrderedDict()

        related_fields = related_names
        result = OrderedDict()

        for rf in related_names:
            named_field = None
            if isinstance(rf, tuple):
                rf, named_field = rf

            rel_field = Obj.getattr(model, rf, None)
            if rel_field and isinstance(rel_field, Manager):
                value_list = [cls.get_id_name_pair(md, named_field=named_field) for md in rel_field.all()]
                result[rf] = value_list
            else:
                result.update(cls.get_id_name_pair(rel_field, named_field=named_field, prefix=rf))
        return result
예제 #12
0
def d(obj, header='', indent=2, **kwargs):
    """
    Var dumps

    :param obj: the object you want to print
    :param indent: indent the json output
    :param header: the text in front of the printout of the object
    :param kwargs: any custom argument to mark the name or key related to the object
    """
    custom_param = ''
    if kwargs:
        custom_param = ' (%s)' % ', '.join(
            ['{}={}'.format(k, v) for k, v in kwargs.items()])

    if type(obj) is str or type(obj) is int or type(obj) is float:
        if header:
            print('{}{} -> {}'.format(header, custom_param, str(obj)))
        else:
            print(str(obj))
        return

    if not isinstance(obj, list) and not isinstance(obj, dict):
        obj = Obj.get_dict(obj)

    if header:
        print('{}{} -> '.format(header, custom_param))
    print(json.dumps(obj, cls=JsonEncoder, skipkeys=True, indent=indent))
예제 #13
0
    def get_related_models(cls, model: models.Model, filter_list=None, exclude_list=None, verbose_key=False,
                          related_fields=None):
        if not related_fields:
            return OrderedDict()

        result = OrderedDict.fromkeys(related_fields, None)

        for rf in related_fields:
            rel_field = Obj.getattr(model, rf, None)
            if rel_field:
                if isinstance(rel_field, Manager):
                    values = []
                    for itm in rel_field.all():
                        values.append(Mdl.get_dict(itm, filter_list, exclude_list, verbose_key))
                    result[rf] = values
                else:
                    result[rf] = Obj.get_dict(rel_field)
        return result
예제 #14
0
def build_list(the_list, attr_name):
    """
    Extract attr from each item in the list

    :param the_list:
    :param attr_name: attribute name support .dot notation (eg. list_of_people|build_list:"contact.phone"
    :return: list
    """
    return [Obj.getattr(x, attr_name, None) for x in the_list]
예제 #15
0
    def get_features(cls,
                     query_set: QuerySet,
                     geometry_field: str,
                     primary_key='pk',
                     filter_list=None,
                     exclude_list=None):
        """
        Convert queryset to a geojson FeatureCollection string.

        :param query_set:   The model QuerySet (ie after filters or .all())
        :param geometry_field:  The field name contains the geometry (point, line, polygon, multipolygon, etc.)
        :param primary_key: The name of the primary key field
        :param filter_list: Which fields to include as the "properties" of the feature.
        :param exclude_list: Which fields to exclude as the "properties" of the feature.
        :return:
        """
        template = '''{ "type": "FeatureCollection",
            "features": [%s]
        }
        '''

        feature_list = []
        sequential_id = 1

        for f in query_set:
            properties = Obj.get_dict(f, filter_list, exclude_list)
            properties.pop(geometry_field, None)
            geometry = Obj.getattr(f, geometry_field)

            feature = dict(type="Feature",
                           geometry=RawJsonString(geometry.geojson),
                           properties=properties)
            feature['id'] = Obj.getattr(f, primary_key, sequential_id)
            feature_json = Json.to_json(feature)
            feature_list.append(feature_json)

            sequential_id += 1

        features = ''
        if feature_list:
            features = ','.join(feature_list)
        return defaultfilters.mark_safe(template % features)
예제 #16
0
    def create(self, manager: str = None):
        model_manager = self.model.objects
        if manager:
            model_manager = Obj.getattr(self.model, manager)

        for i in range(self.qty):
            record = self.model(**self._get_values())
            self.data_list.append(record)
            if len(self.data_list) >= self.batch_size:
                self._bulk_insert(model_manager)
        self._bulk_insert(model_manager)
예제 #17
0
    def str_join(cls, lst, separator=', ', value_attr: str = None):
        if not lst:
            return ''

        str_list = []
        for itm in lst:
            if value_attr is not None:
                itm = Obj.getattr(itm, value_attr)
            itm = str(itm)
            str_list.append(itm)
        return separator.join(str_list)
예제 #18
0
    def get_list(cls, qs: QuerySet):
        """
        Return a list of a dict of each row

        :param qs:
        :return:
        """
        result = []
        for m in qs:
            result.append(Obj.get_dict(m))
        return result
예제 #19
0
    def to_json(cls, qs: QuerySet, related_list: list = None):
        """
        Convert QuerySet to json

        eg. QrSt.to_json(sensor_objects, ['zone', 'facility.name', 'sensor__name']

        :param qs:
        :param related_list: by default no related object is included, this explicitly tell which fields to fetch.
        :return:
        """

        model_list = []
        for m in qs:
            model_dict = Obj.get_dict(m)
            if related_list:
                for rl in related_list:
                    rl = rl.replace('__', '.')
                    attrs = rl.split('.')
                    if attrs:
                        first_attr = attrs.pop(0)
                        cur_obj = Obj.getattr(m, first_attr)
                        cur_dict = Obj.get_dict(cur_obj)
                        model_dict[first_attr] = cur_dict

                        for att, is_last in last_iter(attrs):
                            if cur_obj is None:
                                break

                            nxt = Obj.getattr(cur_obj, att)
                            cur_dict[att] = Obj.get_dict(nxt)
                            cur_obj = nxt

                            if is_last and isinstance(cur_obj, Manager):
                                cur_dict[att] = QrSt.get_list(cur_obj.all())
                            else:
                                cur_dict = cur_dict[att]

            model_list.append(model_dict)

        return Json.to_json(model_list)
예제 #20
0
def get_attr(obj, attr_name):
    """
    Return the index of the list/dict

    :param obj:
    :param attr_name: supports the dot notation
        (eg. person|index:"contact.phone" where contact is attribute of person)
    :return:
    """
    try:
        result = Obj.getattr(obj, attr_name, None)
        return result
    except:
        return None
예제 #21
0
    def get_unique(cls, the_list, default_value=None, unique_attr=None):
        """
        Get a list of unique values in the list, default_value is [] if default_value is set to None.

        :param the_list:
        :param default_value: if none value is []
        :param unique_attr: select your own unique attribute (in case when the object is unhashable
                                or you want your own attr)
        :rtype list
        """
        if default_value is None:
            default_value = []

        if not the_list:
            return default_value

        try:
            # Src: http://stackoverflow.com/questions/480214
            #       /how-do-you-remove-duplicates-from-a-list-in-python-whilst-preserving-order
            # Src: http://www.peterbe.com/plog/uniqifiers-benchmark
            if unique_attr is None:
                added_list = set()
                add_to_added_list = added_list.add  # this static ref for performance reason
                return [
                    x for x in the_list
                    if not (x in added_list or add_to_added_list(x))
                ]

            result = []
            existed_item = {
            }  # dict is much faster than list when checking existence of a key
            for itm in the_list:
                key = Obj.getattr(itm, unique_attr)
                if key not in existed_item:
                    result.append(itm)
                    existed_item[key] = None
            return result
        except Exception as ex:
            log_exception(ex)
            return default_value
예제 #22
0
    def get_id_name_pair(cls, instance: models.Model, named_field=None, prefix=''):
        """
        Get id and name of a model.

        :param instance: instance of a model
        :param named_field: if you want to use non-standard named field, eg. name_field="nick_name"
        :param prefix: prefix this name to the result key. eg. { facility_id:, facility_name: }
        :return:
        :rtype: dict
        """
        if prefix:
            prefix += '_'

        if not instance:
            return {
                prefix + 'id': None,
                prefix + 'name': str(None),
            }

        name_attrs = ['name', 'sensor_name', 'username']

        if named_field:
            print(named_field)
            name_attrs = [named_field] + name_attrs

        try:
            for attr in name_attrs:
                name = Obj.getattr(instance, attr, 'NOT_FOUND!')
                if name != 'NOT_FOUND!':
                    return {
                        prefix + 'id': instance.pk,
                        prefix + 'name': name,
                    }
        except:
            pass

        return {
            prefix + 'id': instance.pk,
            prefix + 'name': str(instance),
        }
예제 #23
0
def join_by(the_list, options):
    """
    Join the list.
        Usage:  facilities|join_by:" ,zone.name"   => facility1 facility2
                facilities|join_by:", ,zone.name"   => facility1, facility2

    :param the_list:
    :param options: comma separated "{separator}, {attribute.inner_attribute}".
    :return: string
    """
    if not the_list:
        return ''
    assert options, 'join_by: Arguments cannot be emptied.'

    if isinstance(the_list, Manager):
        the_list = the_list.all()
    elif callable(the_list):
        the_list = the_list.__call__()

    separator, attr = options.rsplit(',', 1)
    attr = attr.strip()
    return separator.join([Obj.getattr(itm, attr, '').__str__() for itm in the_list])
예제 #24
0
 def get_json_dict(self):
     """
     The dict equivalent of the json object.
     """
     return Obj.get_dict(self, self.json_includes, self.json_excludes)
예제 #25
0
    def test_get_attr(self):
        not_found = 'Not Found!'

        class Test:
            def __init__(self, a, b, other_test=None):
                self.a = a
                self.b = b
                self.other_test = other_test

        my_obj = {
            'hello': 'hello world',
            'obj': {
                'int': 10,
                'arr': [7, 0, 3, 2, 5],
                'none': None,
            }
        }
        sub = Test('sub', 'class')
        parent = Test('parent class', 99, sub)

        self.assertEqual(Obj.getattr(my_obj, 'obj.arr', not_found),
                         my_obj['obj']['arr'])
        self.assertEqual(Obj.getattr(my_obj, 'obj.arr.4', not_found), 5)
        self.assertEqual(Obj.getattr(my_obj, 'obj.arr.7', not_found),
                         not_found)
        self.assertEqual(Obj.getattr(my_obj, 'obj.int', not_found), 10)
        self.assertEqual(Obj.getattr(my_obj, 'obj.none', not_found), None)
        self.assertEqual(Obj.getattr(my_obj, 'hello', not_found),
                         my_obj['hello'])

        self.assertEqual(Obj.getattr(sub, 'a', not_found), sub.a)
        self.assertEqual(Obj.getattr(sub, 'b', not_found), sub.b)
        self.assertEqual(Obj.getattr(sub, 'other_test', not_found),
                         sub.other_test)

        self.assertEqual(Obj.getattr(parent, 'a', not_found), parent.a)
        self.assertEqual(Obj.getattr(parent, 'b', not_found), parent.b)
        self.assertEqual(Obj.getattr(parent, 'other_test', not_found), sub)
        self.assertEqual(Obj.getattr(parent, 'other_test.a', not_found), sub.a)
        self.assertEqual(Obj.getattr(parent, 'other_test.b', not_found), sub.b)
        self.assertEqual(
            Obj.getattr(parent, 'other_test.other_test', not_found),
            sub.other_test)
예제 #26
0
def as_table(data, filter_param=None):
    """
    Turn queryset or list row_dict into a table.
    :param data: queryset|list of [row_dict]
    :param filter_param: comma separated list of column. Syntax: queryset|as_table:'include_me, !not_include, include2'
                            eg. users|as_table:'!age, !password'
                            eg. group|as_table:'name, group_count'
    :return:
    """
    if not data:
        return None

    result = []
    filter_list = []
    exclude_list = []
    model = Obj.getattr(data, 'model', None, False)

    if filter_param:
        filter_param_list = Lst.strip_string(filter_param.split(','))
        for the_filter in filter_param_list:
            assert isinstance(the_filter, str)
            if the_filter.startswith('!'):
                exclude_list.append(the_filter[1:])
            else:
                filter_list.append(the_filter)

    if isinstance(data, dict):
        sub_tables = {}
        for key, row in data.items():
            if isinstance(row, list):
                sub_tables[key] = as_table(row, filter_param)
                continue

            row_dict = Obj.get_dict(row, filter_list, exclude_list, verbose_key=True, get_display=True)
            result.append(row_dict)

        if sub_tables:
            context = {'sub_tables': sub_tables}
            html = render_to_string('lazifier/table_filter/as_table_filter_sub_tables_layout.html', context)
            return mark_safe(html)
    else:
        if isinstance(data, collections.Iterable):
            for row in data:
                row_dict = Obj.get_dict(row, filter_list, exclude_list, verbose_key=True, get_display=True)

                for k, v in row_dict.items():
                    if isinstance(v, list):
                        if v:
                            row_dict[k] = as_table(v, filter_param)

                result.append(row_dict)
        else:
            result.append(Obj.get_dict(data, verbose_key=True))

    if result:
        headers = []
        if model is not None:
            columns = result[0].keys()
            headers = list(Mdl.get_field_verbose(model, columns).values())
        else:
            for k, v in result[0].items():
                if Str.is_int(k):
                    headers.append(type(v).__name__)
                elif type(k) is str and k.islower():
                    headers.append(Str.snake_to_title(k))
                else:
                    headers.append(k)

        context = {'headers': headers, 'data': result}
        html = render_to_string('lazifier/table_filter/as_table_filter_layout.html', context)
    else:
        return None

    return mark_safe(html)