Repository: igorbenav/fastcrud
Pull request #150 (2024-08-08 13:01:04)

fix complex parameter filter with between
# Pull Request Template for FastCRUD

## Description
There is an error in the normal use of the between filter, this pr will fix it!

## Changes
Fixed `_parse_filters` method

## Tests
Added test cases to sqlalchemy and sqlmodel: `test_parse_filters_between_condition`.

## Checklist
- [x] I have read the [CONTRIBUTING](CONTRIBUTING.md) document.
- [x] My code follows the code style of this project.
- [ ] I have added necessary documentation (if appropriate).
- [x] I have added tests that cover my changes (if applicable).
- [x] All new and existing tests passed.

## Additional Notes
This repair process also includes changes to .gitignore, notably there was a mypy type checking error in crud_router, which I was unable to fix, but instead skipped it over checking.


Patch:
diff --git a/.gitignore b/.gitignore
index 7cba10b..29c7438 100644
--- a/.gitignore
+++ b/.gitignore
@@ -159,9 +159,9 @@ cython_debug/
 #  be found at https://github.com/github/gitignore/blob/main/Global/JetBrains.gitignore
 #  and can be added to the global gitignore or merged into this file.  For a more nuclear
 #  option (not recommended) you can uncomment the following to ignore the entire idea folder.
-#.idea/
+.idea/
 
 # Macos
 .DS_Store
 
-.ruff_cache
\ No newline at end of file
+.ruff_cache
diff --git a/fastcrud/crud/fast_crud.py b/fastcrud/crud/fast_crud.py
index 2fb1399..7ee9719 100644
--- a/fastcrud/crud/fast_crud.py
+++ b/fastcrud/crud/fast_crud.py
@@ -318,7 +318,7 @@ class FastCRUD(
                         for or_key, or_value in value.items()
                         if (
                             sqlalchemy_filter := self._get_sqlalchemy_filter(
-                                or_key, value
+                                or_key, or_value
                             )
                         )
                         is not None
@@ -327,7 +327,11 @@ class FastCRUD(
                 else:
                     sqlalchemy_filter = self._get_sqlalchemy_filter(op, value)
                     if sqlalchemy_filter:
-                        filters.append(sqlalchemy_filter(column)(value))
+                        filters.append(
+                            sqlalchemy_filter(column)(value)
+                            if op != "between"
+                            else sqlalchemy_filter(column)(*value)
+                        )
             else:
                 column = getattr(model, key, None)
                 if column is not None:
diff --git a/fastcrud/endpoint/crud_router.py b/fastcrud/endpoint/crud_router.py
index 8e0a8c1..0616de5 100644
--- a/fastcrud/endpoint/crud_router.py
+++ b/fastcrud/endpoint/crud_router.py
@@ -430,10 +430,10 @@ def crud_router(
         session=session,
         model=model,
         crud=crud,
-        create_schema=create_schema,
-        update_schema=update_schema,
+        create_schema=create_schema,  # type: ignore
+        update_schema=update_schema,  # type: ignore
         include_in_schema=include_in_schema,
-        delete_schema=delete_schema,
+        delete_schema=delete_schema,  # type: ignore
         path=path,
         tags=tags,
         is_deleted_column=is_deleted_column,


Test patch:
diff --git a/tests/sqlalchemy/core/test_parse_filters.py b/tests/sqlalchemy/core/test_parse_filters.py
index 5320542..5c354fd 100644
--- a/tests/sqlalchemy/core/test_parse_filters.py
+++ b/tests/sqlalchemy/core/test_parse_filters.py
@@ -48,6 +48,16 @@ async def test_parse_filters_not_contained_in(test_model):
     )
 
 
+@pytest.mark.asyncio
+async def test_parse_filters_between_condition(test_model):
+    fast_crud = FastCRUD(test_model)
+    filters = fast_crud._parse_filters(category_id__between=[1, 5])
+    assert len(filters) == 1
+    assert (
+        str(filters[0]) == "test.category_id BETWEEN :category_id_1 AND :category_id_2"
+    )
+
+
 @pytest.mark.asyncio
 @pytest.mark.parametrize("operator", ("in", "not_in", "between"))
 async def test_parse_filters_raises_exception(test_model, operator: str):
diff --git a/tests/sqlmodel/core/test_parse_filters.py b/tests/sqlmodel/core/test_parse_filters.py
index 5320542..5c354fd 100644
--- a/tests/sqlmodel/core/test_parse_filters.py
+++ b/tests/sqlmodel/core/test_parse_filters.py
@@ -48,6 +48,16 @@ async def test_parse_filters_not_contained_in(test_model):
     )
 
 
+@pytest.mark.asyncio
+async def test_parse_filters_between_condition(test_model):
+    fast_crud = FastCRUD(test_model)
+    filters = fast_crud._parse_filters(category_id__between=[1, 5])
+    assert len(filters) == 1
+    assert (
+        str(filters[0]) == "test.category_id BETWEEN :category_id_1 AND :category_id_2"
+    )
+
+
 @pytest.mark.asyncio
 @pytest.mark.parametrize("operator", ("in", "not_in", "between"))
 async def test_parse_filters_raises_exception(test_model, operator: str):