Showing
11 changed files
with
253 additions
and
57 deletions
| ... | @@ -14,7 +14,8 @@ from aiocache import caches | ... | @@ -14,7 +14,8 @@ from aiocache import caches |
| 14 | 14 | ||
| 15 | from presupuestov1.routers import ( | 15 | from presupuestov1.routers import ( |
| 16 | project, | 16 | project, |
| 17 | - entity | 17 | + entity, |
| 18 | + classifier | ||
| 18 | ) | 19 | ) |
| 19 | 20 | ||
| 20 | 21 | ||
| ... | @@ -40,6 +41,10 @@ app = FastAPI( | ... | @@ -40,6 +41,10 @@ app = FastAPI( |
| 40 | ) | 41 | ) |
| 41 | app.include_router(project.router) | 42 | app.include_router(project.router) |
| 42 | app.include_router(entity.router) | 43 | app.include_router(entity.router) |
| 44 | +app.include_router(classifier.router_objeto) | ||
| 45 | +app.include_router(classifier.router_acteco) | ||
| 46 | +app.include_router(classifier.router_finfun) | ||
| 47 | + | ||
| 43 | 48 | ||
| 44 | 49 | ||
| 45 | @app.on_event('startup') | 50 | @app.on_event('startup') | ... | ... |
| ... | @@ -72,3 +72,31 @@ class TreemapActeco(Base): | ... | @@ -72,3 +72,31 @@ class TreemapActeco(Base): |
| 72 | desc_acteco: Mapped[str | None] = mapped_column(Text) | 72 | desc_acteco: Mapped[str | None] = mapped_column(Text) |
| 73 | parent: Mapped[str | None] = mapped_column(String(9)) | 73 | parent: Mapped[str | None] = mapped_column(String(9)) |
| 74 | devengado: Mapped[float | None] = mapped_column(Numeric(30, 15)) | 74 | devengado: Mapped[float | None] = mapped_column(Numeric(30, 15)) |
| 75 | + | ||
| 76 | + | ||
| 77 | +############################################################################### | ||
| 78 | +# fns | ||
| 79 | +############################################################################### | ||
| 80 | + | ||
| 81 | +def get_entity_connections(entity_id, db, query, ClassObject, object_id): | ||
| 82 | + query_filters = [ | ||
| 83 | + ClassObject.entidad == entity_id, | ||
| 84 | + ] | ||
| 85 | + | ||
| 86 | + return get_clas_entities(query_filters, db, query, ClassObject, object_id) | ||
| 87 | + | ||
| 88 | + | ||
| 89 | +def get_clas_entities(query_filters, db, query, ClassObject, object_id): | ||
| 90 | + if query.gestion is None: | ||
| 91 | + query.gestion = 0 | ||
| 92 | + | ||
| 93 | + query_filters.append(ClassObject.gestion == query.gestion) | ||
| 94 | + | ||
| 95 | + if query.id is not None: | ||
| 96 | + ids = query.id.split(',') | ||
| 97 | + ids = [int(_.strip()) for _ in ids] | ||
| 98 | + | ||
| 99 | + ids = or_([getattr(ClassObject, object_id) == _ for _ in ids]) | ||
| 100 | + query_filters.append(ids) | ||
| 101 | + | ||
| 102 | + return db.query(ClassObject).filter(and_(*query_filters)).all() | ... | ... |
requirements.txt
0 → 100644
routers/classifier.py
0 → 100644
| 1 | +import time | ||
| 2 | + | ||
| 3 | +from typing import List, Any, Optional, Union | ||
| 4 | + | ||
| 5 | +from fastapi import APIRouter, Depends, Request, HTTPException, Body | ||
| 6 | +from sqlalchemy.orm import Session | ||
| 7 | +from sqlalchemy import and_, or_ | ||
| 8 | + | ||
| 9 | +from presupuestov1 import model, schema, constant, schemas, models, search | ||
| 10 | + | ||
| 11 | +from aiocache import cached | ||
| 12 | + | ||
| 13 | + | ||
| 14 | +router_objeto = APIRouter( | ||
| 15 | + prefix='/objeto', | ||
| 16 | + tags=['objeto'], | ||
| 17 | +) | ||
| 18 | + | ||
| 19 | +router_acteco = APIRouter( | ||
| 20 | + prefix='/acteco', | ||
| 21 | + tags=['acteco'], | ||
| 22 | +) | ||
| 23 | + | ||
| 24 | +router_finfun = APIRouter( | ||
| 25 | + prefix='/finfun', | ||
| 26 | + tags=['finfun'], | ||
| 27 | +) | ||
| 28 | + | ||
| 29 | + | ||
| 30 | +############################################################################### | ||
| 31 | +# GET | ||
| 32 | +############################################################################### | ||
| 33 | + | ||
| 34 | +@router_objeto.get('/clasificador', response_model=List[schemas.classifier.ClasObjetos]) | ||
| 35 | +def fetch_object_classifier(db: Session = Depends(model.get_db)): | ||
| 36 | + return _fetch_classifier('objeto', db) | ||
| 37 | + | ||
| 38 | + | ||
| 39 | +@router_acteco.get('/clasificador', response_model=List[schemas.classifier.ClasActeco]) | ||
| 40 | +def fetch_object_classifier(db: Session = Depends(model.get_db)): | ||
| 41 | + return _fetch_classifier('acteco', db) | ||
| 42 | + | ||
| 43 | + | ||
| 44 | +@router_finfun.get('/clasificador', response_model=List[schemas.classifier.ClasFinfun]) | ||
| 45 | +def fetch_object_classifier(db: Session = Depends(model.get_db)): | ||
| 46 | + return _fetch_classifier('finfun', db) | ||
| 47 | + | ||
| 48 | + | ||
| 49 | +@router_objeto.get('/{object_id}', response_model=schemas.classifier.ClasObjetos) | ||
| 50 | +def fetch_clas( | ||
| 51 | + object_id: str, | ||
| 52 | + db: Session = Depends(model.get_db), | ||
| 53 | +): | ||
| 54 | + ClasObjetos = models.classifier.ClasObjetos | ||
| 55 | + return db.query(ClasObjetos).filter( | ||
| 56 | + ClasObjetos.objeto == '{}.0'.format(object_id) | ||
| 57 | + ).one() | ||
| 58 | + | ||
| 59 | + | ||
| 60 | +@router_objeto.get('/{object_id}/entidades', response_model=List[schemas.treemap.TreemapObjeto]) | ||
| 61 | +def fetch_clas( | ||
| 62 | + object_id: str, | ||
| 63 | + db: Session = Depends(model.get_db), | ||
| 64 | +): | ||
| 65 | + Treemap = models.treemap.TreemapObjeto | ||
| 66 | + return models.treemap.get_clas_entities( | ||
| 67 | + [ | ||
| 68 | + Treemap.objeto == object_id | ||
| 69 | + ], db, query, Treemap, 'entidad' | ||
| 70 | + ) | ||
| 71 | + | ||
| 72 | +@router_acteco.get('/{acteco_id}', response_model=schemas.classifier.ClasActeco) | ||
| 73 | +def fetch_clas( | ||
| 74 | + acteco_id: str, | ||
| 75 | + db: Session = Depends(model.get_db), | ||
| 76 | +): | ||
| 77 | + ClasActeco = models.classifier.ClasActeco | ||
| 78 | + return db.query(ClasActeco).filter( | ||
| 79 | + ClasActeco.acteco == acteco_id | ||
| 80 | + ).one() | ||
| 81 | + | ||
| 82 | + | ||
| 83 | +@router_acteco.get('/{acteco_id}/entidades', response_model=List[schemas.treemap.TreemapActeco]) | ||
| 84 | +def fetch_clas( | ||
| 85 | + acteco_id: str, | ||
| 86 | + db: Session = Depends(model.get_db), | ||
| 87 | +): | ||
| 88 | + Treemap = models.treemap.TreemapActeco | ||
| 89 | + return models.treemap.get_clas_entities( | ||
| 90 | + [ | ||
| 91 | + Treemap.acteco == acteco_id | ||
| 92 | + ], db, query, Treemap, 'entidad' | ||
| 93 | + ) | ||
| 94 | + | ||
| 95 | + | ||
| 96 | +@router_finfun.get('/{finfun_id}', response_model=schemas.classifier.ClasFinfun) | ||
| 97 | +def fetch_clas( | ||
| 98 | + finfun_id: str, | ||
| 99 | + db: Session = Depends(model.get_db), | ||
| 100 | +): | ||
| 101 | + ClasFinfun = models.classifier.ClasFinfun | ||
| 102 | + return db.query(ClasFinfun).filter( | ||
| 103 | + ClasFinfun.finfun == finfun_id | ||
| 104 | + ).one() | ||
| 105 | + | ||
| 106 | + | ||
| 107 | +@router_finfun.get('/{finfun_id}/entidades', response_model=List[schemas.treemap.TreemapFinFun]) | ||
| 108 | +def fetch_clas( | ||
| 109 | + finfun_id: str, | ||
| 110 | + db: Session = Depends(model.get_db), | ||
| 111 | +): | ||
| 112 | + Treemap = models.treemap.TreemapFinFun | ||
| 113 | + return models.treemap.get_clas_entities( | ||
| 114 | + [ | ||
| 115 | + Treemap.finfun == finfun_id | ||
| 116 | + ], db, query, Treemap, 'entidad' | ||
| 117 | + ) | ||
| 118 | + | ||
| 119 | + | ||
| 120 | +############################################################################### | ||
| 121 | +# priv | ||
| 122 | +############################################################################### | ||
| 123 | + | ||
| 124 | +def _fetch_classifier(clas, db): | ||
| 125 | + ClassObject = { | ||
| 126 | + 'objeto': models.classifier.ClasObjetos, | ||
| 127 | + 'acteco': models.classifier.ClasActeco, | ||
| 128 | + 'finfun': models.classifier.ClasFinfun, | ||
| 129 | + }[clas] | ||
| 130 | + return db.query(ClassObject).all() |
| ... | @@ -46,7 +46,9 @@ def fetch_entity_objetos( | ... | @@ -46,7 +46,9 @@ def fetch_entity_objetos( |
| 46 | query: schema.QueryParams = Depends(), | 46 | query: schema.QueryParams = Depends(), |
| 47 | ): | 47 | ): |
| 48 | TreemapObjeto = models.treemap.TreemapObjeto | 48 | TreemapObjeto = models.treemap.TreemapObjeto |
| 49 | - return get_entity_connections(entity_id, db, query, TreemapObjeto, 'objeto') | 49 | + return models.treemap.get_entity_connections( |
| 50 | + entity_id, db, query, TreemapObjeto, 'objeto' | ||
| 51 | + ) | ||
| 50 | 52 | ||
| 51 | 53 | ||
| 52 | router.get('/{entity_id:int}/finfuns', response_model=List[schemas.treemap.TreemapFinFun]) | 54 | router.get('/{entity_id:int}/finfuns', response_model=List[schemas.treemap.TreemapFinFun]) |
| ... | @@ -56,7 +58,9 @@ def fetch_entity_finfuns( | ... | @@ -56,7 +58,9 @@ def fetch_entity_finfuns( |
| 56 | query: schema.QueryParams = Depends(), | 58 | query: schema.QueryParams = Depends(), |
| 57 | ): | 59 | ): |
| 58 | TreemapFinFun = models.treemap.TreemapFinFun | 60 | TreemapFinFun = models.treemap.TreemapFinFun |
| 59 | - return get_entity_connections(entity_id, db, query, TreemapFinFun, 'finfun') | 61 | + return models.treemap.get_entity_connections( |
| 62 | + entity_id, db, query, TreemapFinFun, 'finfun' | ||
| 63 | + ) | ||
| 60 | 64 | ||
| 61 | 65 | ||
| 62 | @router.get('/{entity_id:int}/actecos', response_model=List[schemas.treemap.TreemapActeco]) | 66 | @router.get('/{entity_id:int}/actecos', response_model=List[schemas.treemap.TreemapActeco]) |
| ... | @@ -66,29 +70,7 @@ def fetch_entity_actecos( | ... | @@ -66,29 +70,7 @@ def fetch_entity_actecos( |
| 66 | query: schema.QueryParams = Depends(), | 70 | query: schema.QueryParams = Depends(), |
| 67 | ): | 71 | ): |
| 68 | TreemapActeco = models.treemap.TreemapActeco | 72 | TreemapActeco = models.treemap.TreemapActeco |
| 69 | - return get_entity_connections(entity_id, db, query, TreemapActeco, 'acteco') | 73 | + return models.treemap.get_entity_connections( |
| 74 | + entity_id, db, query, TreemapActeco, 'acteco' | ||
| 75 | + ) | ||
| 70 | 76 | ||
| 71 | - | ||
| 72 | -############################################################################### | ||
| 73 | -# Private | ||
| 74 | -############################################################################### | ||
| 75 | - | ||
| 76 | -def get_entity_connections(entity_id, db, query, ClassObject, object_id): | ||
| 77 | - if query.gestion is None: | ||
| 78 | - query.gestion = 0 | ||
| 79 | - | ||
| 80 | - query_filters = [ | ||
| 81 | - ClassObject.entidad == entity_id, | ||
| 82 | - ClassObject.gestion == query.gestion, | ||
| 83 | - ] | ||
| 84 | - | ||
| 85 | - print(query.id is not None) | ||
| 86 | - | ||
| 87 | - if query.id is not None: | ||
| 88 | - ids = query.id.split(',') | ||
| 89 | - ids = [int(_.strip()) for _ in ids] | ||
| 90 | - | ||
| 91 | - ids = or_([getattr(ClassObject, object_id) == _ for _ in ids]) | ||
| 92 | - query_filters.append(ids) | ||
| 93 | - | ||
| 94 | - return db.query(ClassObject).filter(and_(*query_filters)).all() | ||
| ... | \ No newline at end of file | ... | \ No newline at end of file | ... | ... |
| ... | @@ -34,15 +34,23 @@ def fetch_search( | ... | @@ -34,15 +34,23 @@ def fetch_search( |
| 34 | query: schema.SearchQueryParams = Depends(), | 34 | query: schema.SearchQueryParams = Depends(), |
| 35 | ): | 35 | ): |
| 36 | if query.q is None or len(query.q.strip()) < 3: | 36 | if query.q is None or len(query.q.strip()) < 3: |
| 37 | - return [] | 37 | + return { |
| 38 | + 'facet_counts': [], | ||
| 39 | + 'found': 0, | ||
| 40 | + 'out_of': 0, | ||
| 41 | + 'page': 0, | ||
| 42 | + 'search_time_ms': 0, | ||
| 43 | + 'hits': [], | ||
| 44 | + } | ||
| 38 | 45 | ||
| 39 | - return do_search(query.q, query.page, query.is_class) | 46 | + return search.do_search( |
| 47 | + query.q, query.page, query.is_class, query.class_, query.order | ||
| 48 | + ) | ||
| 40 | 49 | ||
| 41 | 50 | ||
| 42 | ############################################################################### | 51 | ############################################################################### |
| 43 | # GET | 52 | # GET |
| 44 | ############################################################################### | 53 | ############################################################################### |
| 45 | 54 | ||
| 46 | -# @cached(ttl=10) | ||
| 47 | -def do_search(query, page, is_class): | ||
| 48 | - return search.do_search(query, page, is_class) | ||
| ... | \ No newline at end of file | ... | \ No newline at end of file |
| 55 | +def do_search(query, page, is_class, class_): | ||
| 56 | + return search.do_search(query, page, is_class, class_) | ... | ... |
| ... | @@ -11,8 +11,10 @@ class OrmBaseModel(BaseModel): | ... | @@ -11,8 +11,10 @@ class OrmBaseModel(BaseModel): |
| 11 | 11 | ||
| 12 | class SearchQueryParams(BaseModel): | 12 | class SearchQueryParams(BaseModel): |
| 13 | page: Optional[int] = Query(default=1) | 13 | page: Optional[int] = Query(default=1) |
| 14 | - q: Optional[str] = Query(default=None) | 14 | + q: Optional[str] = Query(default=None, max_length=128) |
| 15 | + order: Optional[str] = Query(default=None, max_length=5) | ||
| 15 | is_class: Optional[bool] = Query(default=None) | 16 | is_class: Optional[bool] = Query(default=None) |
| 17 | + class_: Optional[str] = Query(default=None) | ||
| 16 | 18 | ||
| 17 | class QueryParams(BaseModel): | 19 | class QueryParams(BaseModel): |
| 18 | id: Optional[str] = Query(default=None) | 20 | id: Optional[str] = Query(default=None) | ... | ... |
| 1 | from typing import Any | 1 | from typing import Any |
| 2 | 2 | ||
| 3 | from presupuestov1.schema import OrmBaseModel | 3 | from presupuestov1.schema import OrmBaseModel |
| 4 | +from pydantic import create_model | ||
| 4 | 5 | ||
| 5 | 6 | ||
| 6 | class ClasInstitucional(OrmBaseModel): | 7 | class ClasInstitucional(OrmBaseModel): |
| ... | @@ -28,6 +29,13 @@ class ClasInstitucional(OrmBaseModel): | ... | @@ -28,6 +29,13 @@ class ClasInstitucional(OrmBaseModel): |
| 28 | n_gestiones: int | None | 29 | n_gestiones: int | None |
| 29 | 30 | ||
| 30 | 31 | ||
| 32 | +def get_clasdesc(name): | ||
| 33 | + return create_model( | ||
| 34 | + '_ClasDesc{}'.format(name), | ||
| 35 | + **{'gestion': str, 'desc_{}'.format(name): str}, | ||
| 36 | + ) | ||
| 37 | + | ||
| 38 | + | ||
| 31 | class ClasObjetos(OrmBaseModel): | 39 | class ClasObjetos(OrmBaseModel): |
| 32 | nivel: str | None | 40 | nivel: str | None |
| 33 | objeto: str | 41 | objeto: str |
| ... | @@ -35,7 +43,7 @@ class ClasObjetos(OrmBaseModel): | ... | @@ -35,7 +43,7 @@ class ClasObjetos(OrmBaseModel): |
| 35 | gestiones: str | None | 43 | gestiones: str | None |
| 36 | n_gestiones: int | None | 44 | n_gestiones: int | None |
| 37 | n_variaciones: int | None | 45 | n_variaciones: int | None |
| 38 | - descripciones: list[dict[str, Any]] | None | 46 | + descripciones: list[get_clasdesc('objeto')] | None |
| 39 | 47 | ||
| 40 | 48 | ||
| 41 | class ClasRubros(OrmBaseModel): | 49 | class ClasRubros(OrmBaseModel): |
| ... | @@ -45,7 +53,7 @@ class ClasRubros(OrmBaseModel): | ... | @@ -45,7 +53,7 @@ class ClasRubros(OrmBaseModel): |
| 45 | gestiones: str | None | 53 | gestiones: str | None |
| 46 | n_gestiones: int | None | 54 | n_gestiones: int | None |
| 47 | n_variaciones: int | None | 55 | n_variaciones: int | None |
| 48 | - descripciones: list[dict[str, Any]] | None | 56 | + descripciones: list[get_clasdesc('rubro')] | None |
| 49 | 57 | ||
| 50 | 58 | ||
| 51 | class ClasFinfun(OrmBaseModel): | 59 | class ClasFinfun(OrmBaseModel): |
| ... | @@ -55,4 +63,14 @@ class ClasFinfun(OrmBaseModel): | ... | @@ -55,4 +63,14 @@ class ClasFinfun(OrmBaseModel): |
| 55 | gestiones: str | None | 63 | gestiones: str | None |
| 56 | n_gestiones: int | None | 64 | n_gestiones: int | None |
| 57 | n_variaciones: int | None | 65 | n_variaciones: int | None |
| 58 | - descripciones: list[dict[str, Any]] | None | 66 | + descripciones: list[get_clasdesc('finfun')] | None |
| 67 | + | ||
| 68 | + | ||
| 69 | +class ClasActeco(OrmBaseModel): | ||
| 70 | + nivel: str | None | ||
| 71 | + acteco: str | ||
| 72 | + desc_acteco: str | None | ||
| 73 | + gestiones: str | None | ||
| 74 | + n_gestiones: int | None | ||
| 75 | + n_variaciones: int | None | ||
| 76 | + descripciones: list[get_clasdesc('acteco')] | None | ... | ... |
| 1 | +import numpy as np | ||
| 2 | + | ||
| 1 | from presupuestov1.schema import OrmBaseModel | 3 | from presupuestov1.schema import OrmBaseModel |
| 4 | +from pydantic import field_serializer | ||
| 2 | 5 | ||
| 3 | 6 | ||
| 4 | -class TreemapObjeto(OrmBaseModel): | 7 | +class Treemap(OrmBaseModel): |
| 5 | gestion: int | 8 | gestion: int |
| 6 | entidad: int | 9 | entidad: int |
| 7 | - objeto: int | ||
| 8 | nivel: str | None | 10 | nivel: str | None |
| 9 | - desc_objeto: str | None | ||
| 10 | parent: int | None | 11 | parent: int | None |
| 11 | devengado: float | None | 12 | devengado: float | None |
| 12 | 13 | ||
| 14 | + @field_serializer('devengado') | ||
| 15 | + def do_round(self, v): | ||
| 16 | + if v is not None: | ||
| 17 | + return np.round(v, 2) | ||
| 13 | 18 | ||
| 14 | -class TreemapFinFun(OrmBaseModel): | 19 | + |
| 15 | - gestion: int | 20 | +class TreemapObjeto(Treemap): |
| 16 | - entidad: int | 21 | + objeto: str |
| 17 | - finfun: int | 22 | + desc_objeto: str | None |
| 18 | - nivel: str | None | 23 | + |
| 24 | + | ||
| 25 | +class TreemapFinFun(Treemap): | ||
| 26 | + finfun: str | ||
| 19 | desc_finfun: str | None | 27 | desc_finfun: str | None |
| 20 | - parent: int | None | ||
| 21 | - devengado: float | None | ||
| 22 | 28 | ||
| 23 | 29 | ||
| 24 | -class TreemapActeco(OrmBaseModel): | 30 | +class TreemapActeco(Treemap): |
| 25 | - gestion: int | 31 | + acteco: str |
| 26 | - entidad: int | ||
| 27 | - acteco: int | ||
| 28 | - nivel: str | None | ||
| 29 | desc_actividad: str | None | 32 | desc_actividad: str | None |
| 30 | - parent: int | None | ||
| 31 | - devengado: float | None | ... | ... |
| ... | @@ -18,6 +18,7 @@ schema = { | ... | @@ -18,6 +18,7 @@ schema = { |
| 18 | {'name': 'gestion', 'type': 'int32', 'facet': True}, | 18 | {'name': 'gestion', 'type': 'int32', 'facet': True}, |
| 19 | {'name': 'devengado', 'type': 'float'}, | 19 | {'name': 'devengado', 'type': 'float'}, |
| 20 | {'name': 'is_class', 'type': 'bool'}, | 20 | {'name': 'is_class', 'type': 'bool'}, |
| 21 | + {'name': 'class_', 'type': 'string'}, | ||
| 21 | {'name': 'texto', 'type': 'string'}, | 22 | {'name': 'texto', 'type': 'string'}, |
| 22 | {'name': 'metadatos', 'type': 'string'}, | 23 | {'name': 'metadatos', 'type': 'string'}, |
| 23 | ], | 24 | ], |
| ... | @@ -33,8 +34,10 @@ search_parameters = { | ... | @@ -33,8 +34,10 @@ search_parameters = { |
| 33 | } | 34 | } |
| 34 | 35 | ||
| 35 | 36 | ||
| 36 | - | 37 | +AVAILABLE_CLASSES = [ |
| 37 | -def do_search(query, page, is_class): | 38 | + 'programa_proyecto', 'entidad', 'objeto', 'finfun', 'acteco' |
| 39 | +] | ||
| 40 | +def do_search(query, page, is_class, class_=None, order=None): | ||
| 38 | search_parameters_ = search_parameters.copy() | 41 | search_parameters_ = search_parameters.copy() |
| 39 | search_parameters_['q'] = query | 42 | search_parameters_['q'] = query |
| 40 | 43 | ||
| ... | @@ -47,9 +50,18 @@ def do_search(query, page, is_class): | ... | @@ -47,9 +50,18 @@ def do_search(query, page, is_class): |
| 47 | 50 | ||
| 48 | search_parameters_['filter_by'] = filter_c | 51 | search_parameters_['filter_by'] = filter_c |
| 49 | 52 | ||
| 50 | - if (page is not None) and (page > 0): | 53 | + if (class_ is not None): |
| 54 | + class_ = [_ for _ in class_.split(',') if _ in AVAILABLE_CLASSES] | ||
| 55 | + if len(class_): | ||
| 56 | + search_parameters_['filter_by'] = 'class_:[{}]'.format(', '.join(class_)) | ||
| 57 | + | ||
| 58 | + if (page is not None) and (page > 0) and (page < 100): | ||
| 51 | search_parameters_['page'] = page | 59 | search_parameters_['page'] = page |
| 52 | 60 | ||
| 61 | + search_parameters_['sort_by'] = 'devengado:desc' | ||
| 62 | + if order == 'asc': | ||
| 63 | + search_parameters_['sort_by'] = 'devengado:asc' | ||
| 64 | + | ||
| 53 | return client.collections[COLLECTION].documents.search( | 65 | return client.collections[COLLECTION].documents.search( |
| 54 | search_parameters_ | 66 | search_parameters_ |
| 55 | ) | 67 | ) | ... | ... |
-
Please register or login to post a comment