Skip to content
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

Better typing model property #240

Open
OndrejIT opened this issue Mar 1, 2023 · 3 comments
Open

Better typing model property #240

OndrejIT opened this issue Mar 1, 2023 · 3 comments

Comments

@OndrejIT
Copy link

OndrejIT commented Mar 1, 2023

Hi,
I have a model property in the django framework that returns a list of dict
Is there any way to type it more easily than using a resolver?

Currently my code looks like this:

My django model:

class MySite:
	@property
	def player_data(self):
		data = [
			{
				"src": signed_movie_url(self.project_path, "video-1080p.mp4"),
				"size": 1080,
				"type": "video/mp4",
			},
			{
				"src": signed_movie_url(self.project_path, "video-720p.mp4"),
				"size": 720,
				"type": "video/mp4",
			},
			{
				"src": signed_movie_url(self.project_path, "video-540p.mp4"),
				"size": 540,
				"type": "video/mp4",
			},
		]

		return data

My types:

@strawberry.type
class SiteType:
	@strawberry.type()
	class PlayerSiteDataType:
		src: str
		size: int
		type: str

	@staticmethod
	def player_data(root):
		return [SiteType.PlayerSiteDataType(**i) for i in root.player_data]

	name: str
	player_data: List[PlayerSiteDataType] = strawberry.field(resolver=player_data)

Thanks.

Upvote & Fund

  • We're using Polar.sh so you can upvote and help fund this issue.
  • We receive the funding once the issue is completed & confirmed by you.
  • Thank you in advance for helping prioritize & fund our backlog.
Fund with Polar
@OndrejIT
Copy link
Author

OndrejIT commented Mar 1, 2023

I'm rewriting my api in graphene_django to strawberry.
Currently the code I use for graphene_django is much more readable:

class SiteType(DjangoObjectType):
	class PlayerSiteDataType(graphene.ObjectType):
		src = graphene.String()
		size = graphene.String()
		type = graphene.String()

	player_data = graphene.List(PlayerSiteDataType)

	class Meta:
		model = MySite
		fields = ("name",)

@vitosamson
Copy link

If it helps, I created a custom type JsonType for resolving dicts. This allows us to avoid writing custom resolvers for these sorts of objects:

def json_field():
    """
    Creates a field and resolver for fields on a json blob.
    """

    def resolver(root: dict, info: Info):
        if isinstance(info.return_type, StrawberryOptional):
            return root.get(info.python_name, None)
        return root[info.python_name]

    return strawberry.field(resolver=resolver)


@strawberry.type
class JsonType:
    """
    Models the type of a json blob, which needs specific typing for graphql.
    """

    def __init_subclass__(cls) -> None:
        for field_name in cls.__annotations__.keys():
            setattr(cls, field_name, json_field())

You would just need to have your PlayerSiteDataType subclass JsonType like so:

@strawberry.type
class SiteType:
	@strawberry.type()
	class PlayerSiteDataType(JsonType):
		src: str
		size: int
		type: str

	name: str
	player_data: List[PlayerSiteDataType]

@OndrejIT
Copy link
Author

OndrejIT commented Mar 2, 2023

@vitosamson it looks good. Thank you!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants