|
18 | 18 | from fastapi_jsonapi import BadRequest |
19 | 19 | from fastapi_jsonapi.common import get_relationship_info_from_field_metadata |
20 | 20 | from fastapi_jsonapi.data_layers.base import BaseDataLayer |
21 | | -from fastapi_jsonapi.data_layers.filtering.sqlalchemy import create_filters_and_joins |
22 | | -from fastapi_jsonapi.data_layers.sorting.sqlalchemy import Node |
| 21 | +from fastapi_jsonapi.data_layers.sqla.query_building import ( |
| 22 | + build_filter_expressions, |
| 23 | + build_sort_expressions, |
| 24 | + prepare_relationships_info, |
| 25 | +) |
23 | 26 | from fastapi_jsonapi.data_typing import TypeModel, TypeSchema |
24 | 27 | from fastapi_jsonapi.exceptions import ( |
25 | 28 | HTTPException, |
@@ -353,13 +356,7 @@ async def get_collection(self, qs: QueryStringManager, view_kwargs: Optional[dic |
353 | 356 |
|
354 | 357 | await self.before_get_collection(qs, view_kwargs) |
355 | 358 |
|
356 | | - query = self.query(view_kwargs) |
357 | | - |
358 | | - if filters_qs := qs.filters: |
359 | | - query = self.filter_query(query, filters_qs) |
360 | | - |
361 | | - if sorts := qs.get_sorts(schema=self.schema): |
362 | | - query = self.sort_query(query, sorts) |
| 359 | + query = self.apply_filters_and_sorts(self.query(view_kwargs), qs) |
363 | 360 |
|
364 | 361 | objects_count = await self.get_collection_count(query, qs, view_kwargs) |
365 | 362 |
|
@@ -679,49 +676,31 @@ async def get_related_objects_list( |
679 | 676 |
|
680 | 677 | return list(related_objects) |
681 | 678 |
|
682 | | - def filter_query(self, query: Select, filter_info: Optional[list]) -> Select: |
683 | | - """ |
684 | | - Filter query according to jsonapi 1.0. |
685 | | -
|
686 | | - :param query: sqlalchemy query to sort. |
687 | | - :param filter_info: filter information. |
688 | | - :return: the sorted query. |
689 | | - """ |
690 | | - if filter_info: |
691 | | - filters, joins = create_filters_and_joins( |
692 | | - model=self.model, |
693 | | - filter_info=filter_info, |
694 | | - schema=self.schema, |
695 | | - ) |
696 | | - |
697 | | - for i_join in joins: |
698 | | - query = query.join(*i_join) |
| 679 | + def apply_filters_and_sorts(self, query: Select, qs: QueryStringManager): |
| 680 | + filters, sorts = qs.filters, qs.sorts |
| 681 | + relationships_info = prepare_relationships_info(self.model, self.schema, filters, sorts) |
699 | 682 |
|
700 | | - query = query.where(filters) |
| 683 | + for info in relationships_info.values(): |
| 684 | + query = query.join(info.aliased_model, info.join_column) |
701 | 685 |
|
702 | | - return query |
703 | | - |
704 | | - def sort_query(self, query: Select, sort_info: list) -> Select: |
705 | | - """ |
706 | | - Sort query according to jsonapi 1.0. |
707 | | -
|
708 | | - :param query: sqlalchemy query to sort. |
709 | | - :param sort_info: sort information. |
710 | | - :return: the sorted query. |
711 | | - """ |
712 | | - if not sort_info: |
713 | | - return query |
| 686 | + if filters: |
| 687 | + filter_expressions = build_filter_expressions( |
| 688 | + filter_item={"and": filters}, |
| 689 | + target_model=self.model, |
| 690 | + target_schema=self.schema, |
| 691 | + relationships_info=relationships_info, |
| 692 | + ) |
| 693 | + query = query.where(filter_expressions) |
| 694 | + |
| 695 | + if sorts: |
| 696 | + sort_expressions = build_sort_expressions( |
| 697 | + sort_items=sorts, |
| 698 | + target_model=self.model, |
| 699 | + target_schema=self.schema, |
| 700 | + relationships_info=relationships_info, |
| 701 | + ) |
| 702 | + query = query.order_by(*sort_expressions) |
714 | 703 |
|
715 | | - sorts = [] |
716 | | - joins = [] |
717 | | - for filter_or_sort in sort_info: |
718 | | - filters_or_sort, join = Node(self.model, filter_or_sort, self.schema).resolve() |
719 | | - sorts.append(filters_or_sort) |
720 | | - joins.extend(join) |
721 | | - for i_join in joins: |
722 | | - query = query.join(*i_join) |
723 | | - for i_sort in sorts: |
724 | | - query = query.order_by(i_sort) |
725 | 704 | return query |
726 | 705 |
|
727 | 706 | def paginate_query(self, query: Select, paginate_info: PaginationQueryStringManager) -> Select: |
|
0 commit comments