def filter_query(cls, query, filter_field, filter_text, sort_field, sort_course, page, count, model, multif, clazz, default_sort=None): """ Метод для дополнительной фильтрации. """ if filter_field and filter_text: debug(u"Фильтрация %s." % clazz) if filter_field in multif.keys(): flds = multif[filter_field] subq = [] for fld in flds: rels = fld.split(".") """ Проверяем фильтрацию на связанные модели. Если есть, то надо сначала связать эти таблицы. """ if len(rels) == 1: debug(u"Фильтрация %s по модели." % fld) sss = [] for ss in filter_text.split(" "): sss.append(model.__table__.columns[fld].ilike( "%"+ss+"%")) subq.append(and_(*sss)) else: debug(u"Фильтрация %s по связанной модели %s." % ( clazz, fld)) rel_m, attr = rels cl = get_relation_model(model, rel_m) query = query.join(cl) subq.append(cl.__table__.columns[attr].ilike( "%"+filter_text+"%")) query = query.filter(or_(*subq)) else: query = query.filter( model.__table__.columns[filter_field].ilike( "%"+filter_text+"%") ) debug(u"Фильтрация %s успешна." % clazz) if sort_field and sort_course: query = query.order_by( {'desc': desc, 'asc': asc}[sort_course]( model.__table__.columns[sort_field]) ) elif not default_sort: query = query.order_by(desc(model.id)) else: ord, fld = default_sort query = query.order_by( {'desc': desc, 'asc': asc}[ord](model.__table__.columns[fld]) ) max_ = query.count() if page and count: query = query.offset((page - 1) * count).limit(count) records = query.all() count_ = query.count() return records, max_, count_
def post_save(self, obj, data, create_new=False): """ Сохранение связанных моделей, если вдруг приходит в параметрах. Смотрим :attr_json, если в описании есть аттрибуты связанных моделей (Пример: {'price_post': Attr(attribute='price.price_post')}, - это значит что если в запросе придет параметр 'price.price_post', то ищем связанную модель 'price' в нашей модели, если нашли, то изменяем ее атрибуты, если нет, то создаем новую модель и привязываем к нашей). @New version 0.1: Появилось поле ChoiceType, которое тоже нужно прокидывать в рест, в качестве значения в БД, либо в расшифровке. Специально для него, тоже проставляем `attribute. В итоге надо как то искать такие поля и игнорировать, иначе система работает с ними как со связанными через модельку. """ if data: attr_relation = self._get_attr_relation() list_created_obj = [] for key, attr in attr_relation: objnest = obj full_p = attr.attribute chain_models, _, at = attr.attribute.rpartition(".") for chain_model in chain_models.split("."): try: #Ищем поля ChoiceType try: if objnest == obj \ and hasattr(objnest._sa_class_manager[chain_model].property, 'columns') \ and objnest._sa_class_manager[chain_model].property.columns \ and isinstance(objnest._sa_class_manager[chain_model].property.columns[0].type, ChoiceType): break except AttributeError as exc: error(unicode(exc)) raise Exception(exc) value = getattr(objnest, chain_model) if not value and key in data: rel_model = get_relation_model(objnest, chain_model) instance = rel_model() setattr(objnest, chain_model, instance) objnest = getattr(objnest, chain_model) else: objnest = value except AttributeError as exc: break except Exception as exc: pass else: try: setattr(objnest, at, data[full_p]) except (KeyError, AttributeError): pass else: if objnest not in list_created_obj: list_created_obj.append(objnest) for objs in list_created_obj: db.session.add(objs)