from django.db import models import operator from django.db.models import Q from ox.text import smartSplit from ox.django.fields import DictField from django.core.paginator import Paginator, InvalidPage, EmptyPage def splitSearch(string): ret = [] for s in smartSplit(string): word = s.replace("'", "").replace('"', '') ret.append(word) return ret class ItfModel(models.Model): fts_fields = [] fk_filters = [] # related_models = [] sort_fields = [] hasComments = True class Meta: abstract = True def list_dict(self): return {} def info_dict(self): return self.get_dict() def get_dict(self): return self.get(self._get_fields().keys()) def get(self, props): typ = type(props) if typ == list: ret = {} for p in props: ret[p] = self._get_property(p) return ret elif typ == str: return _get_property(props) else: return False def _get_property(self, prop): fields = self._get_fields() if prop in fields.keys(): field_type = fields[prop] if field_type in ["TextField", "CharField", "IntegerField"]: return self.__getattribute__(prop) elif field_type == "ImageField": imagefield = self.__getattribute__(prop) return imagefield.url if imagefield.name != '' else '' elif field_type == "ForeignKey": return self._get_fk(prop) elif field_type == "ManyToMany": return self._get_m2m(prop) elif prop.lower() in self.related_models: return self._get_related(prop) else: try: val = self.__getattribute__(prop) if type(val).__name__ == 'instancemethod' and prop in self.getters: return val() else: return val except: return False #FIXME def _get_fk(self, prop): prop = prop.replace("_id", "") return self.__getattribute__(prop).get_dict() # def _get_related_objects(self, fk_field): def _get_m2m(self, prop): ret = [] for o in self.__getattribute__(prop).all(): ret.append(o.get_dict()) return ret def _get_related(self, prop): attr = prop.lower() + "_set" ret = [] for o in self.__getattribute__(attr).all(): ret.append(o.get_dict()) return ret @classmethod def _get_fields(kls): ret = {} for f in kls._meta.fields: ret[f.get_attname()] = type(f).__name__ return ret @classmethod def fts(kls, qset, search): terms = splitSearch(search) qobjects = [] for t in terms: for f in kls.fts_fields: qstring = f + '__icontains' qobject = Q(**{qstring:t}) qobjects.append(qobject) return qset.filter(reduce(operator.or_, qobjects)) ''' eg. fks = { 'somefield': [1, 5, 7], 'someotherfield': [3] } ''' @classmethod def filter_by_fks(kls, qset, fks): qobjects = [] for key in fks.keys(): field = getField(kls._meta.fields, key) if field: # rel_class = field.related.parent_model for i in fks[key]: qobject = Q(**{field.name: i}) qobjects.append(qobject) return qset.filter(reduce(operator.or_, qobjects)) @classmethod def get_fk_objects(kls): ret = {} for f in kls.fk_filters: ret[f] = [] field = getField(kls._meta.fields, f) rel_class = field.related.parent_model for o in rel_class.objects.all(): ret[f].append({ 'id': o.id, 'title': unicode(o) }) return ret @classmethod def get_list(kls, data): options = { 'page_no': 1, 'list_size': 8, 'search': '', 'sort': [], 'range': [0,50] } options.update(data) ret = [] page_no = options['page_no'] list_size = options['list_size'] try: qset = kls.get_qset() except: qset = kls.objects.all() search = options['search'] if search != '': qset = kls.fts(qset, search) sort = options['sort'] if sort != []: for s in sort: if s['operator'] == '-': operator = '-' else: operator = '' sort = operator + s['key'] qset = qset.order_by(sort) r0 = options['range'][0] r1 = options['range'][1] results = qset[r0:r1] for r in results: ret.append(r.list_dict()) return ret @classmethod def get_qset(kls): ''' Override this method in your model class to define a custom queryset instead of objects.all(), for instance, to always exclude unpublished items. ''' raise NotImplementedError def getField(fields, name): for f in fields: if f.name == name: return f return False def site_config(): with open(settings.SITE_CONFIG) as f: site_config = json.load(f) site_config['keys'] = {} for key in site_config['itemKeys']: site_config['keys'][key['id']] = key site_config['_findKeys'] = {} for key in site_config['findKeys']: site_config['_findKeys'][key['id']] = key return site_config