- 
          
- 
                Notifications
    You must be signed in to change notification settings 
- Fork 145
Description
Summary
We're using Strawberry Graphql Django in our app and we would need a totalCount attribute for our queries in order show it in the frontend. I had previously raised blb-ventures/strawberry-django-plus#190 in which it was suggested to use a relay node for this purpose.
However, considering our entire application now is built on top of non-relay nodes, we don't necessarily want to change everything to relay nodes at this point. However, we have figured out two approaches to include our custom pagination logic by overriding the StrawberryDjangoField class. Before committing to an approach, we wanted to get some feedback from the team as to which one seems to be more aligned with the library.
Problem Statement
We have create a PaginatedConnection class which we are using as a type for our query nodes to include the count metadata as follows.
@strawberry.type
class PaginationConnection(Generic[ModelReturnType]):
    page_info: PageInfo
    results: List[ModelReturnType]
    
#which is being used as
paginated_records: PaginationConnection[RecordNode] = CustomStrawberryField()
However, this breaks the strawberry django internal functions as it can't identify the django_type (and consequently django_model) properly anymore.
Proposed Solutions
- Override the django_type fieldinCustomStrawberryField-> Here we are overriding the property to modify the origin to be theRecordNodeinstead ofPaginationConnection. (We saw that this approach is being followed to resolved the relay node type internally indjango_type)
    # Because our return type for a paginated node is different than a regular StrawberryNode,
    # we need to figure our the actual StrawberryNode type in order to get results
    @functools.cached_property
    def django_type(self) -> type[WithStrawberryDjangoObjectDefinition] | None:
        # Storing this value so that it can be reassigned to self.type
        origin = self.type
        origin_node = None
        object_definition = get_object_definition(origin)
        if object_definition and issubclass(
            object_definition.origin, PaginationConnection
        ):
            origin_node = object_definition.type_var_map.get("ModelReturnType")
            if isinstance(origin, LazyType):
                origin_node = origin.resolve_type()
        self.type = origin_node
        result_type = super().django_type
        self.type = origin
- Passing the Django model explicitly in CustomStrawberryFieldand then setting the internaldjango_modelin the__init__function. This will directly set thedjango_modelno matter what the result of `django_type is.
    def __init__(
        self,
        django_model: type[models.Model],
        result_formatter_class: Type[CustomResultFormatMixin],
        *args,
        **kwargs,
    ):
        self.django_model = django_model
        self.result_formatter = result_formatter_class()
        self.non_paginated_qset: QuerySet
        self.paginated_qset: QuerySet
        super().__init__(*args, **kwargs)
        
        
     #And then calling the field as 
     paginated_records: PaginationConnection[RecordNode] = CustomStrawberryField(django_model=Record)
As we aren't sure about any proposed future changes to the library's internal API, we wanted to be double sure we are making the correct decision in terms of customizing the StrawberryDjangoField. Please let us know what you folks think about it.