88from starlette import status
99from sqlalchemy .sql import Select
1010
11+ from fastapi_sa_orm_filter .dto import ParsedFilter
1112from fastapi_sa_orm_filter .exceptions import SAFilterOrmException
13+ from fastapi_sa_orm_filter .interfaces import QueryParser
1214from fastapi_sa_orm_filter .operators import Operators as ops
13- from fastapi_sa_orm_filter .parsers import FilterQueryParser , OrderByQueryParser
14- from fastapi_sa_orm_filter .sa_expression_builder import SAFilterExpressionBuilder
15+ from fastapi_sa_orm_filter .parsers import StringQueryParser
16+ from fastapi_sa_orm_filter .sa_expression_builder import SAFilterExpressionBuilder , SAOrderByExpressionBuilder
1517
1618
1719class FilterCore :
@@ -36,10 +38,11 @@ def __init__(
3638 'field_name': [startswith, eq, in_],
3739 'field_name': [contains, like]
3840 }
41+ :param select_query_part: custom select query part (select(model).join(model1))
3942 """
4043 self .model = model
4144 self ._allowed_filters = allowed_filters
42- self .select_query_part = select_query_part
45+ self .select_sql_query = select_query_part
4346
4447 def get_query (self , custom_filter : str ) -> Select [Any ]:
4548 """
@@ -50,7 +53,6 @@ def get_query(self, custom_filter: str) -> Select[Any]:
5053 created_at__between=2023-05-01,2023-05-05|
5154 category__eq=Medicine&
5255 order_by=-id
53- :param select_query_part: custom select query part (select(model).join(model1))
5456
5557 :return:
5658 select(model)
@@ -63,56 +65,49 @@ def get_query(self, custom_filter: str) -> Select[Any]:
6365 model.category == 'Medicine'
6466 ).order_by(model.id.desc())
6567 """
66- split_query = self ._split_by_order_by (custom_filter )
6768 try :
68- complete_query = self ._get_complete_query (* split_query )
69+ query_parser = self ._get_query_parser (custom_filter )
70+ filter_query , order_by_query = query_parser .get_parsed_filter ()
71+ complete_query = self ._get_complete_query (filter_query , order_by_query )
6972 except SAFilterOrmException as e :
7073 raise HTTPException (status_code = status .HTTP_400_BAD_REQUEST , detail = e .args [0 ])
7174 return complete_query
7275
73- def _get_complete_query (self , filter_query_str : str , order_by_query_str : str | None = None ) -> Select [Any ]:
74- select_query_part = self .get_select_query_part ()
75- filter_query_part = self ._get_filter_query_part (filter_query_str )
76- complete_query = select_query_part .filter (* filter_query_part )
77- group_query_part = self .get_group_by_query_part ()
78- if group_query_part :
79- complete_query = complete_query .group_by (* group_query_part )
80- if order_by_query_str is not None :
81- order_by_query = self .get_order_by_query_part (order_by_query_str )
82- complete_query = complete_query .order_by (* order_by_query )
83- return complete_query
76+ def _get_complete_query (
77+ self , filter_query : list [list [ParsedFilter ]] | list , order_by_query : list [str ] | list
78+ ) -> Select [Any ]:
79+ select_sa_query = self .get_select_query_part ()
80+ filter_sa_query = self ._get_filter_sa_query (filter_query )
81+ group_by_sa_query = self ._get_group_by_sa_query ()
82+ order_by_sa_query = self ._get_order_by_sa_query (order_by_query )
83+ return select_sa_query .filter (* filter_sa_query ).group_by (* group_by_sa_query ).order_by (* order_by_sa_query )
8484
8585 def get_select_query_part (self ) -> Select [Any ]:
86- if self .select_query_part is not None :
87- return self .select_query_part
86+ if self .select_sql_query is not None :
87+ return self .select_sql_query
8888 return select (self .model )
8989
90- def _get_filter_query_part (self , filter_query_str : str ) -> list [Any ]:
91- conditions = self ._get_filter_query (filter_query_str )
92- if len (conditions ) == 0 :
93- return conditions
90+ def _get_filter_sa_query (self , filter_query : list [list [ParsedFilter ]] | list ) -> list [BinaryExpression ] | list :
91+ if len (filter_query ) == 0 :
92+ return []
93+ sa_builder = SAFilterExpressionBuilder (self .model )
94+ conditions = sa_builder .get_expressions (filter_query )
9495 return [or_ (* conditions )]
9596
96- def get_group_by_query_part (self ) -> list :
97- return []
97+ def _get_order_by_sa_query (self , order_by_query : list [str ] | list ) -> list [UnaryExpression ]:
98+ if len (order_by_query ) == 0 :
99+ return []
100+ sa_builder = SAOrderByExpressionBuilder (self .model )
101+ return sa_builder .get_order_by_query (order_by_query )
98102
99- def get_order_by_query_part (self , order_by_query_str : str ) -> list [UnaryExpression ]:
100- order_by_parser = OrderByQueryParser (self .model )
101- return order_by_parser .get_order_by_query (order_by_query_str )
103+ def _get_group_by_sa_query (self ) -> list [BinaryExpression ] | list :
104+ group_query_part = self .get_group_by_query_part ()
105+ if len (group_query_part ) == 0 :
106+ return []
107+ return group_query_part
102108
103- def _get_filter_query (self , custom_filter : str ) -> list [BinaryExpression ]:
104- filter_conditions = []
105- if custom_filter == "" :
106- return filter_conditions
109+ def get_group_by_query_part (self ) -> list :
110+ return []
107111
108- parser = FilterQueryParser (custom_filter , self ._allowed_filters )
109- parsed_filters = parser .get_parsed_query ()
110- sa_builder = SAFilterExpressionBuilder (self .model )
111- return sa_builder .get_expressions (parsed_filters )
112-
113- @staticmethod
114- def _split_by_order_by (query ) -> list :
115- split_query = [query_part .strip ("&" ) for query_part in query .split ("order_by=" )]
116- if len (split_query ) > 2 :
117- raise SAFilterOrmException ("Use only one order_by directive" )
118- return split_query
112+ def _get_query_parser (self , custom_filter : str ) -> QueryParser :
113+ return StringQueryParser (custom_filter , self ._allowed_filters )
0 commit comments