from graphene_django.converter import convert_django_field from .registry import get_global_registry from .models import SIGsAPIModel from .fields import SIGsAPIForeignKey, SIGsAPIField, SIGsAPIStringField, SIGsAPIDateTimeField, SIGsAPIDetailsField, SIGsAPIIdField, SIGsAPIManyToOne, SIGsAPIOneToOneField, SIGSAPIOneToManyField, SIGsToOneRelation, SIGsToManyRelation from graphene import String, Field, Dynamic, List from graphene.types.objecttype import ObjectType, ObjectTypeOptions import inspect from functools import singledispatch from collections import OrderedDict from graphene.types.utils import yank_fields_from_attrs # Conversão dos Fields para Django Models @convert_django_field.register(SIGsAPIForeignKey) def convert_field_to_sigs_model(field, registry=None): model = field.target_class # Ignore o registry do graphene_django e use o registry do SIGsAPI registry = get_global_registry() def dynamic_type(): _type = registry.get_type_for_model(model) if not _type: return return Field(_type, required = not field.null) return Dynamic(dynamic_type) # Conversão dos Fields para SIGs Models @singledispatch def convert_sigs_field(field, registry): raise Exception("Tipo do field {field} desconhecido, não é possível converter para Graphene Field.".format(field = field)) @convert_sigs_field.register(SIGsAPIStringField) @convert_sigs_field.register(SIGsAPIIdField) def convert_sigs_field_to_string(field, registry): return String() @convert_sigs_field.register(SIGsToOneRelation) @convert_sigs_field.register(SIGsAPIManyToOne) def convert_sigs_field_to_sigsmodel(field, registry): model = field.target_class def dynamic_type(): _type = registry.get_type_for_model(model) if not _type: return return Field(_type, required=not field.null) return Dynamic(dynamic_type) @convert_sigs_field.register(SIGsToManyRelation) @convert_sigs_field.register(SIGSAPIOneToManyField) def convert_sigs_field_to_sigsmodel(field, registry): model = field.target_class def dynamic_type(): _type = registry.get_type_for_model(model) if not _type: return return List(_type, required=not field.null) return Dynamic(dynamic_type) def construct_fields( model, registry ): _model_fields = model._meta.fields fields = OrderedDict() for name, field in _model_fields.items(): fields[name] = convert_sigs_field(field, registry) return fields class SIGsObjectTypeOptions(ObjectTypeOptions): model = None # SIGsObjectType class SIGsObjectType(ObjectType): @classmethod def __init_subclass_with_meta__( cls, model=None, fields=None, interfaces=(), **options, ): registry = get_global_registry() sigs_fields = yank_fields_from_attrs( construct_fields(model, registry), _as=Field, ) _meta = SIGsObjectTypeOptions(cls) _meta.model = model _meta.fields = sigs_fields super(SIGsObjectType, cls).__init_subclass_with_meta__( _meta=_meta, interfaces=interfaces, **options ) registry.register(cls) def resolve_id(self, info): return self.pk @classmethod def is_type_of(cls, root, info): if isinstance(root, cls): return True if not inspect.isclass(root.__class__) and issubclass(root.__class__, SIGsAPIModel): raise Exception(('Instância não pertence a uma classe SIGsModel "{}".').format(root)) model = root._meta.model #._meta.concrete_model return model == cls._meta.model @classmethod def get_queryset(cls, queryset, info): return queryset @classmethod def get_node(cls, info, id): queryset = cls.get_queryset(cls._meta.model.objects, info) try: return queryset.get(pk=id) except cls._meta.model.DoesNotExist: return None