strawberry-graphql / strawberry-django

Strawberry GraphQL Django extension
MIT License
393 stars 115 forks source link

how to create a single field filter? #351

Closed hyusetiawan closed 10 months ago

hyusetiawan commented 10 months ago

I am trying to define a field on a type that can be filtered, the field only returns 1 object so no list. my attempt is this:

    chat: auto = strawberry_django.field(
        field_name="chat_set",
        filters=ChatFilter,
        default_factory=lambda: None,
    )

but it still returns a list, I wonder if there is a way to express, something like : self.chat_set.get(filters**) instead of self.chat_set.filter(filters**)?

Upvote & Fund

Fund with Polar

hyusetiawan commented 10 months ago

here's another attempt that I have:


    @strawberry_django.field
    async def chat(self, gid: str, info: AppInfo) -> Union["TypeChat", None]:
        user = await get_user_from_request(info)
        return await Chat.objects.aget(author=user, gid=gid)  # type: ignore

gives me the following error:

strawberry.exceptions.unresolved_field_type.UnresolvedFieldTypeError: Could not resolve the type of 'chat'. Check that the class is accessible from the global module scope.

I am following this: https://github.com/bellini666/strawberry-django-demo/blob/main/demo/order/schema.py#L36 the one that is different is the typing, because of the circular import here's the rest of the code:

import strawberry
import strawberry_django
from incredibly.gql.context import AppInfo
from incredibly.lib.auth import get_user_from_request
from incredibly.models.chat import Chat
from user import models
from strawberry import auto
from typing import TYPE_CHECKING, Annotated, Union
from strawberry_django.filters import FilterLookup
from asgiref.sync import sync_to_async

if TYPE_CHECKING:
    from .chat import TypeChat

@strawberry_django.filter(Chat)
class ChatFilter:
    gid: str
    # title: FilterLookup[str]

@strawberry_django.type(models.User, name="User")
class TypeUser:
    gid: str
    first_name: auto
    last_name: auto
    email: auto

    chats: list[
        Annotated["TypeChat", strawberry.lazy(".chat")]
    ] = strawberry_django.field(
        field_name="chat_set",
        default_factory=lambda: [],
    )

    @strawberry.field
    async def name(self) -> str:
        print(
            await sync_to_async(self.chat_set.get)(gid="chtcllvfvghn0003lzstm3nqhzh2")
        )
        return self.first_name + " " + self.last_name

    @strawberry_django.field
    async def chat(self, gid: str, info: AppInfo) -> Union["TypeChat", None]:
        user = await get_user_from_request(info)
        return await Chat.objects.aget(author=user, gid=gid)  # type: ignore
hyusetiawan commented 10 months ago

here's my attempt that works but it looks so janky, I am sure there are easier ways to do this, perhaps the decorator way?

async def resolver_chat(self):
    return await Chat.objects.afirst()

 chat: Annotated["TypeChat", strawberry.lazy(".chat")] = strawberry_django.field(
        resolver=resolver_chat,
        graphql_type=Annotated["TypeChat", strawberry.lazy(".chat")],
    )

it is still reporting the following typing error although it works:

Expression of type "StrawberryDjangoField" cannot be assigned to declared type "TypeChat"
  "StrawberryDjangoField" is incompatible with "TypeChat"Pylance[reportGeneralTypeIssues]
bellini666 commented 10 months ago

Hi @hyusetiawan ,

Sorry, I have not been able to look at this yet. I saw that you closed it, is this resolved for you?

hyusetiawan commented 10 months ago

yeah, after compiling from several places, I came up with the following that seems to work:

@strawberry_django.field
async def chat(self, gid: str, root: models.User) -> TypeChatRef | None:
try:
return cast(TypeChat, await root.chat_set.aget(gid=gid))
except:
return None

Thank you for following up Thiago!

On Wed, Aug 30, 2023 at 2:18 PM Thiago Bellini Ribeiro < @.***> wrote:

Hi @hyusetiawan https://github.com/hyusetiawan ,

Sorry, I have not been able to look at this yet. I saw that you closed it, is this resolved for you?

— Reply to this email directly, view it on GitHub https://github.com/strawberry-graphql/strawberry-graphql-django/issues/351#issuecomment-1699856725, or unsubscribe https://github.com/notifications/unsubscribe-auth/AAIDQCBZCJTIJLE4AALEBFDXX6U25ANCNFSM6AAAAAA4CCX3RI . You are receiving this because you were mentioned.Message ID: @.*** .com>