-
-
Notifications
You must be signed in to change notification settings - Fork 123
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
feat: New Paginated generic to be used as a wrapped for paginated results #642
Conversation
Codecov ReportAttention: Patch coverage is
Additional details and impacted files@@ Coverage Diff @@
## main #642 +/- ##
==========================================
+ Coverage 88.77% 88.99% +0.21%
==========================================
Files 41 41
Lines 3607 3724 +117
==========================================
+ Hits 3202 3314 +112
- Misses 405 410 +5 ☔ View full report in Codecov by Sentry. |
253ccc7
to
2ca008c
Compare
e32366b
to
eda46e7
Compare
Reviewer's Guide by SourceryThis pull request introduces a new generic type User journey diagram for querying paginated resultsjourney
title User Journey for Querying Paginated Results
section Query Fruits
User -> GraphQL API: Request fruits with pagination
GraphQL API -> Database: Fetch fruits with pagination
Database -> GraphQL API: Return paginated fruits
GraphQL API -> User: Return paginated fruits with totalCount and pageInfo
section Query Colors with Nested Fruits
User -> GraphQL API: Request colors with nested fruits pagination
GraphQL API -> Database: Fetch colors and nested fruits with pagination
Database -> GraphQL API: Return paginated colors and nested fruits
GraphQL API -> User: Return paginated colors with nested fruits, totalCount, and pageInfo
Class diagram for the new Paginated generic typeclassDiagram
class Paginated {
+Optional~QuerySet~ queryset
+OffsetPaginationInput pagination
+PaginatedInfo page_info()
+int total_count()
+list~NodeType~ results()
+int get_total_count()
+Optional~QuerySet~ get_paginated_queryset()
}
class OffsetPaginationInput {
+int offset
+int limit
}
class PaginatedInfo {
+int limit
+int offset
}
Paginated --> OffsetPaginationInput
Paginated --> PaginatedInfo
File-Level Changes
Assessment against linked issues
Possibly linked issues
Tips and commandsInteracting with Sourcery
Customizing Your ExperienceAccess your dashboard to:
Getting Help
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Hey @bellini666 - I've reviewed your changes - here's some feedback:
Overall Comments:
- Great addition of the
Paginated
generic type. The implementation is solid, well-integrated with existing components, and thoroughly tested. The extensive test coverage is particularly commendable.
Here's what I looked at during the review
- 🟢 General issues: all looks good
- 🟢 Security: all looks good
- 🟢 Testing: all looks good
- 🟢 Complexity: all looks good
- 🟡 Documentation: 1 issue found
Help me be more useful! Please click 👍 or 👎 on each comment and I'll use the feedback to improve your reviews.
ce87a26
to
4c9c068
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
this is cool, I left some initial comments 😊
@strawberry_django.field | ||
def average_price(self) -> Decimal: | ||
if self.queryset is None: | ||
return Decimal(0) | ||
|
||
return self.queryset.aggregate(Avg("price"))["price__avg"] | ||
|
||
@strawberry_django.field | ||
def paginated_average_price(self) -> Decimal: | ||
paginated_queryset = self.get_paginated_queryset() | ||
if paginated_queryset is None: | ||
return Decimal(0) | ||
|
||
return paginated_queryset.aggregate(Avg("price"))["price__avg"] |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
neat!
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
obs. this also works for relay connections (I've done some similar stuff in the past like this :)
@@ -574,6 +574,15 @@ def _optimize_prefetch_queryset( | |||
else: | |||
mark_optimized = False | |||
|
|||
if isinstance(field.type, type) and issubclass(field.type, Paginated): | |||
pagination = field_kwargs.get("pagination") | |||
qs = apply_window_pagination( |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
is there a way to customise the queryset? should we document it?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Hrm I haven't thought about that... good idea! Make it similar to the Connection
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I refactored everything to be used similarly to how the Connection
works, with an extension.
It is in this commit: b5a226d
(#642)
b5a226d
to
9705ab0
Compare
docs/guide/pagination.md
Outdated
|
||
@strawberry.type | ||
class Query: | ||
@straberry.offset_paginated(OffsetPaginated[Fruit], order=order) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Typo here @bellini666 but this is really gorgeous, overall, I'm loving this feature.
return queryset | ||
``` | ||
|
||
This would produce the following schema: |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm a huge fan of adding the resulting schema to the docs for each of these things, it's been a big point of frustration for me with the docs not seeing how it should come out.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks for the feedback! I'm planing on doing some improvements to the docs soon and I'll do more of this!
@bellini666 and @patrick91 I'd love to see this released, anything I can do to help expedite? |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Amazing stuff, the docs are 👌
|
||
### Default limit for pagination | ||
|
||
The default limit for pagination is set to `100`. This can be changed in the |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🙇♂️
Fix #408
Paginated
generic typePaginated
with StrawberryDjangoFieldSummary by Sourcery
Introduce a new Paginated generic type for handling paginated results, integrate it with StrawberryDjangoField, and update documentation and tests to support this new feature.
New Features:
Enhancements:
Documentation:
Tests: