strawberry-django-plus icon indicating copy to clipboard operation
strawberry-django-plus copied to clipboard

How to have custom ordering method on gql.django.ordering.order class definition

Open insomniac34 opened this issue 1 year ago • 6 comments

Hello!

So, I have a Django model, Invoice, which let's say has two fields, id and amount, a float.

class Invoice(models.Model):
    id = models.PrimaryKey(...)
    
    @property
    def amount(self) -> float:
        # calculates amount on the fly, returns a float

Likewise, I use Strawberry Django Plus to define a custom Filter class for this (yes I know it's not particularly efficient, but it does work):

@gql.django.filters.filter(Invoice, lookups=True)
class InvoiceFilter:
    id: gql.auto
   
    amount_range: List[float] | None

    def filter_amount_range(self, queryset: InvoiceManager):
        if self.amount_range is not None and len(self.amount_range) == 2:
            # convert queryset into a list so I can access my aggregate InvoiceManager calculated values
            return ListAsQuerySet([
                invoice
                for invoice in queryset.all()
                if invoice.amount >= self.amount_range[0]
                and invoice.amount <= self.amount_range[1]
            ], model=Invoice)
        return queryset

In the above Filter definition, I am able to define custom filtering logic for the Invoice, and I have access to my custom Django InvoiceManager.

Similarly, I am trying to implement custom sorting logic in my InvoiceOrder class, in the same fashion as the above filter snippet; however I can't find any documentation or examples on how to do this. Here is what I have so far, which is failing with cannot resolve keyword 'amount'. Choices are: 'id'. no matter what I try to return from order_amount.

@gql.django.ordering.order(Invoice)
class InvoiceOrder:
    #this field exists on the underlying Invoice django model class.
    id: gql.auto

    # this field is an @property method on the underlying django model class
    amount: gql.auto

    def order_amount(self, queryset):
        # how do I return an ordering definition here?
        pass

Is there a way for me to define custom sorting logic in a gql.django.ordering.order class?

thank you!

insomniac34 avatar Feb 07 '23 23:02 insomniac34