Skip to content

Instantly share code, notes, and snippets.

Show Gist options
  • Save marcelblijleven/045b47032341dca212fd18869aa89b49 to your computer and use it in GitHub Desktop.
Save marcelblijleven/045b47032341dca212fd18869aa89b49 to your computer and use it in GitHub Desktop.
Strawberry Django get node from global id
from base64 import b64encode as _b64encode, b64decode as _b64decode
from typing import Type
from django.db.models import Model
from django.shortcuts import get_object_or_404
_encoding = "utf-8"
def decode_base64(value: str) -> str:
"""Decode a base64 string"""
return _b64decode(value).decode(_encoding)
def encode_base64(value: str) -> str:
"""Encode a string to base64"""
return _b64encode(value.encode(_encoding)).decode(_encoding)
def encode_global_id(typename: str, id_: Union[int, str]) -> str:
"""
Encodes the typename and id into a base64 encoded global id
"""
return encode_base64(f"{typename}:{id_}")
def decode_global_id(global_id: str) -> tuple[str, Union[str, int]]:
"""
Decodes the global id into a tuple of typename and id
"""
data = decode_base64(global_id)
typename, _, raw_id = data.partition(":")
try:
id_ = int(raw_id)
return typename, id_
except ValueError:
return typename, raw_id
def get_node_from_global_id(global_id: str) -> Model:
"""
Use the schema to retrieve the type definition of the
provided global id. If the type definition origin is a
Strawberry Django Field, query the orm using the id from
the global id
"""
from path.to.your.schema import schema
typename, _id = decode_global_id(global_id)
if (type_definition := schema.get_type_by_name(typename)) is None:
raise ValueError(f"Could not find a type definition for {typename}")
if not hasattr(type_definition.origin, "_django_type"):
raise ValueError(
f"Could not get node from global id, "
"{typename} is not a Strawberry Django type"
)
model: Type[Model] = type_definition.origin._django_type.model
return get_object_or_404(model, pk=_id)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment