diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 26af2d8d..a0989f0f 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -18,7 +18,7 @@ repos: - id: check-xml - id: check-symlinks - repo: https://github.com/astral-sh/ruff-pre-commit - rev: v0.8.6 + rev: v0.9.1 hooks: - id: ruff-format - id: ruff diff --git a/poetry.lock b/poetry.lock index 96f3d4c8..0d39bd96 100644 --- a/poetry.lock +++ b/poetry.lock @@ -1,4 +1,4 @@ -# This file is automatically @generated by Poetry 2.0.0 and should not be changed by hand. +# This file is automatically @generated by Poetry 2.0.1 and should not be changed by hand. [[package]] name = "asgiref" @@ -289,14 +289,14 @@ doc = ["Sphinx", "sphinx-rtd-theme", "sphinxcontrib-spelling"] [[package]] name = "faker" -version = "33.3.0" +version = "33.3.1" description = "Faker is a Python package that generates fake data for you." optional = false python-versions = ">=3.8" groups = ["dev"] files = [ - {file = "Faker-33.3.0-py3-none-any.whl", hash = "sha256:ae074d9c7ef65817a93b448141a5531a16b2ea2e563dc5774578197c7c84060c"}, - {file = "faker-33.3.0.tar.gz", hash = "sha256:2abb551a05b75d268780b6095100a48afc43c53e97422002efbfc1272ebf5f26"}, + {file = "Faker-33.3.1-py3-none-any.whl", hash = "sha256:ac4cf2f967ce02c898efa50651c43180bd658a7707cfd676fcc5410ad1482c03"}, + {file = "faker-33.3.1.tar.gz", hash = "sha256:49dde3b06a5602177bc2ad013149b6f60a290b7154539180d37b6f876ae79b20"}, ] [package.dependencies] @@ -690,30 +690,30 @@ six = ">=1.5" [[package]] name = "ruff" -version = "0.8.6" +version = "0.9.1" description = "An extremely fast Python linter and code formatter, written in Rust." optional = false python-versions = ">=3.7" groups = ["dev"] files = [ - {file = "ruff-0.8.6-py3-none-linux_armv6l.whl", hash = "sha256:defed167955d42c68b407e8f2e6f56ba52520e790aba4ca707a9c88619e580e3"}, - {file = "ruff-0.8.6-py3-none-macosx_10_12_x86_64.whl", hash = "sha256:54799ca3d67ae5e0b7a7ac234baa657a9c1784b48ec954a094da7c206e0365b1"}, - {file = "ruff-0.8.6-py3-none-macosx_11_0_arm64.whl", hash = "sha256:e88b8f6d901477c41559ba540beeb5a671e14cd29ebd5683903572f4b40a9807"}, - {file = "ruff-0.8.6-py3-none-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:0509e8da430228236a18a677fcdb0c1f102dd26d5520f71f79b094963322ed25"}, - {file = "ruff-0.8.6-py3-none-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:91a7ddb221779871cf226100e677b5ea38c2d54e9e2c8ed847450ebbdf99b32d"}, - {file = "ruff-0.8.6-py3-none-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:248b1fb3f739d01d528cc50b35ee9c4812aa58cc5935998e776bf8ed5b251e75"}, - {file = "ruff-0.8.6-py3-none-manylinux_2_17_ppc64.manylinux2014_ppc64.whl", hash = "sha256:bc3c083c50390cf69e7e1b5a5a7303898966be973664ec0c4a4acea82c1d4315"}, - {file = "ruff-0.8.6-py3-none-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:52d587092ab8df308635762386f45f4638badb0866355b2b86760f6d3c076188"}, - {file = "ruff-0.8.6-py3-none-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:61323159cf21bc3897674e5adb27cd9e7700bab6b84de40d7be28c3d46dc67cf"}, - {file = "ruff-0.8.6-py3-none-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:7ae4478b1471fc0c44ed52a6fb787e641a2ac58b1c1f91763bafbc2faddc5117"}, - {file = "ruff-0.8.6-py3-none-musllinux_1_2_aarch64.whl", hash = "sha256:0c000a471d519b3e6cfc9c6680025d923b4ca140ce3e4612d1a2ef58e11f11fe"}, - {file = "ruff-0.8.6-py3-none-musllinux_1_2_armv7l.whl", hash = "sha256:9257aa841e9e8d9b727423086f0fa9a86b6b420fbf4bf9e1465d1250ce8e4d8d"}, - {file = "ruff-0.8.6-py3-none-musllinux_1_2_i686.whl", hash = "sha256:45a56f61b24682f6f6709636949ae8cc82ae229d8d773b4c76c09ec83964a95a"}, - {file = "ruff-0.8.6-py3-none-musllinux_1_2_x86_64.whl", hash = "sha256:496dd38a53aa173481a7d8866bcd6451bd934d06976a2505028a50583e001b76"}, - {file = "ruff-0.8.6-py3-none-win32.whl", hash = "sha256:e169ea1b9eae61c99b257dc83b9ee6c76f89042752cb2d83486a7d6e48e8f764"}, - {file = "ruff-0.8.6-py3-none-win_amd64.whl", hash = "sha256:f1d70bef3d16fdc897ee290d7d20da3cbe4e26349f62e8a0274e7a3f4ce7a905"}, - {file = "ruff-0.8.6-py3-none-win_arm64.whl", hash = "sha256:7d7fc2377a04b6e04ffe588caad613d0c460eb2ecba4c0ccbbfe2bc973cbc162"}, - {file = "ruff-0.8.6.tar.gz", hash = "sha256:dcad24b81b62650b0eb8814f576fc65cfee8674772a6e24c9b747911801eeaa5"}, + {file = "ruff-0.9.1-py3-none-linux_armv6l.whl", hash = "sha256:84330dda7abcc270e6055551aca93fdde1b0685fc4fd358f26410f9349cf1743"}, + {file = "ruff-0.9.1-py3-none-macosx_10_12_x86_64.whl", hash = "sha256:3cae39ba5d137054b0e5b472aee3b78a7c884e61591b100aeb544bcd1fc38d4f"}, + {file = "ruff-0.9.1-py3-none-macosx_11_0_arm64.whl", hash = "sha256:50c647ff96f4ba288db0ad87048257753733763b409b2faf2ea78b45c8bb7fcb"}, + {file = "ruff-0.9.1-py3-none-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:f0c8b149e9c7353cace7d698e1656ffcf1e36e50f8ea3b5d5f7f87ff9986a7ca"}, + {file = "ruff-0.9.1-py3-none-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:beb3298604540c884d8b282fe7625651378e1986c25df51dec5b2f60cafc31ce"}, + {file = "ruff-0.9.1-py3-none-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:39d0174ccc45c439093971cc06ed3ac4dc545f5e8bdacf9f067adf879544d969"}, + {file = "ruff-0.9.1-py3-none-manylinux_2_17_ppc64.manylinux2014_ppc64.whl", hash = "sha256:69572926c0f0c9912288915214ca9b2809525ea263603370b9e00bed2ba56dbd"}, + {file = "ruff-0.9.1-py3-none-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:937267afce0c9170d6d29f01fcd1f4378172dec6760a9f4dface48cdabf9610a"}, + {file = "ruff-0.9.1-py3-none-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:186c2313de946f2c22bdf5954b8dd083e124bcfb685732cfb0beae0c47233d9b"}, + {file = "ruff-0.9.1-py3-none-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3f94942a3bb767675d9a051867c036655fe9f6c8a491539156a6f7e6b5f31831"}, + {file = "ruff-0.9.1-py3-none-musllinux_1_2_aarch64.whl", hash = "sha256:728d791b769cc28c05f12c280f99e8896932e9833fef1dd8756a6af2261fd1ab"}, + {file = "ruff-0.9.1-py3-none-musllinux_1_2_armv7l.whl", hash = "sha256:2f312c86fb40c5c02b44a29a750ee3b21002bd813b5233facdaf63a51d9a85e1"}, + {file = "ruff-0.9.1-py3-none-musllinux_1_2_i686.whl", hash = "sha256:ae017c3a29bee341ba584f3823f805abbe5fe9cd97f87ed07ecbf533c4c88366"}, + {file = "ruff-0.9.1-py3-none-musllinux_1_2_x86_64.whl", hash = "sha256:5dc40a378a0e21b4cfe2b8a0f1812a6572fc7b230ef12cd9fac9161aa91d807f"}, + {file = "ruff-0.9.1-py3-none-win32.whl", hash = "sha256:46ebf5cc106cf7e7378ca3c28ce4293b61b449cd121b98699be727d40b79ba72"}, + {file = "ruff-0.9.1-py3-none-win_amd64.whl", hash = "sha256:342a824b46ddbcdddd3abfbb332fa7fcaac5488bf18073e841236aadf4ad5c19"}, + {file = "ruff-0.9.1-py3-none-win_arm64.whl", hash = "sha256:1cd76c7f9c679e6e8f2af8f778367dca82b95009bc7b1a85a47f1521ae524fa7"}, + {file = "ruff-0.9.1.tar.gz", hash = "sha256:fd2b25ecaf907d6458fa842675382c8597b3c746a2dde6717fe3415425df0c17"}, ] [[package]] @@ -767,14 +767,14 @@ doc = ["sphinx"] [[package]] name = "strawberry-graphql" -version = "0.257.0" +version = "0.258.0" description = "A library for creating GraphQL APIs" optional = false python-versions = "<4.0,>=3.9" groups = ["main"] files = [ - {file = "strawberry_graphql-0.257.0-py3-none-any.whl", hash = "sha256:07781c1448c94dc533bce8372d1561e7723bdcee901ac1593b2231953e4c5333"}, - {file = "strawberry_graphql-0.257.0.tar.gz", hash = "sha256:4f95c432fe6091df7e910e9ab3de2ae6cee80183208b669544ef6129d6b6e916"}, + {file = "strawberry_graphql-0.258.0-py3-none-any.whl", hash = "sha256:041adda6e9a97ca337793f6c07fe4db0a9793226907394a00022782f132040ec"}, + {file = "strawberry_graphql-0.258.0.tar.gz", hash = "sha256:3975c638f751e9b87cefd5eb1a29c1f33e639b1f218f199578114fb839dec94c"}, ] [package.dependencies] @@ -930,4 +930,4 @@ enum = ["django-choices-field"] [metadata] lock-version = "2.1" python-versions = ">=3.9,<4.0" -content-hash = "9341bda910863b2495b2b99a0b2d28407337203f80b9bb08c348583dff1ee852" +content-hash = "b56ab4859455a9ef65d81a1e23a020830dfd310ff0a4325577d5ace4dbf7390f" diff --git a/pyproject.toml b/pyproject.toml index 1a6cccb0..06d7c234 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -36,7 +36,7 @@ django = ">=4.2" asgiref = ">=3.8" django-choices-field = { version = ">=2.2.2", optional = true } django-debug-toolbar = { version = ">=3.4", optional = true } -strawberry-graphql = ">=0.257.0" +strawberry-graphql = ">=0.258.0" django-tree-queries = "^0.19.0" [tool.poetry.group.dev.dependencies] @@ -54,7 +54,7 @@ pytest-django = "^4.1.0" pytest-mock = "^3.5.1" pytest-snapshot = "^0.9.0" pytest-watch = "^4.2.0" -ruff = "^0.8.5" +ruff = "^0.9.1" django-polymorphic = "^3.1.0" setuptools = "^75.1.0" psycopg2 = "^2.9.9" diff --git a/strawberry_django/fields/field.py b/strawberry_django/fields/field.py index 34187518..1d65ea15 100644 --- a/strawberry_django/fields/field.py +++ b/strawberry_django/fields/field.py @@ -767,6 +767,7 @@ def connection( metadata: Mapping[Any, Any] | None = None, directives: Sequence[object] | None = (), extensions: Sequence[FieldExtension] = (), + max_results: int | None = None, filters: type | None = UNSET, order: type | None = UNSET, only: TypeOrSequence[str] | None = None, @@ -795,6 +796,7 @@ def connection( metadata: Mapping[Any, Any] | None = None, directives: Sequence[object] | None = (), extensions: Sequence[FieldExtension] = (), + max_results: int | None = None, filters: type | None = UNSET, order: type | None = UNSET, only: TypeOrSequence[str] | None = None, @@ -821,6 +823,7 @@ def connection( metadata: Mapping[Any, Any] | None = None, directives: Sequence[object] | None = (), extensions: Sequence[FieldExtension] = (), + max_results: int | None = None, filters: type | None = UNSET, order: type | None = UNSET, only: TypeOrSequence[str] | None = None, @@ -892,7 +895,10 @@ def connection( https://relay.dev/graphql/connections.htm """ - extensions = [*extensions, StrawberryDjangoConnectionExtension()] + extensions = [ + *extensions, + StrawberryDjangoConnectionExtension(max_results=max_results), + ] f = field_cls( python_name=None, django_name=field_name, diff --git a/strawberry_django/optimizer.py b/strawberry_django/optimizer.py index 70f5c75e..b56340f4 100644 --- a/strawberry_django/optimizer.py +++ b/strawberry_django/optimizer.py @@ -570,6 +570,7 @@ def _optimize_prefetch_queryset( related_field_id=related_field_id, offset=slice_metadata.start, limit=slice_metadata.end - slice_metadata.start, + max_results=connection_extension.max_results, ) else: mark_optimized = False diff --git a/strawberry_django/pagination.py b/strawberry_django/pagination.py index 46baa39e..3522bd00 100644 --- a/strawberry_django/pagination.py +++ b/strawberry_django/pagination.py @@ -171,6 +171,7 @@ def apply_window_pagination( related_field_id: str, offset: int = 0, limit: Optional[int] = UNSET, + max_results: Optional[int] = None, ) -> _QS: """Apply pagination using window functions. @@ -211,7 +212,11 @@ def apply_window_pagination( if limit is UNSET: settings = strawberry_django_settings() - limit = settings["PAGINATION_DEFAULT_LIMIT"] + limit = ( + max_results + if max_results is not None + else settings["PAGINATION_DEFAULT_LIMIT"] + ) # Limit == -1 means no limit. sys.maxsize is set by relay when paginating # from the end to as a way to mimic a "not limit" as well