mirror of
https://github.com/graphql-python/graphene-django.git
synced 2025-07-13 17:52:19 +03:00
Improved registry, raising only when constructing the schema.
This commit is contained in:
parent
4a60da3c36
commit
eadd63d096
|
@ -25,7 +25,7 @@ You retrieve using the function ``get_global_registry`` in
|
||||||
model = ReporterModel
|
model = ReporterModel
|
||||||
|
|
||||||
global_registry = get_global_registry
|
global_registry = get_global_registry
|
||||||
global_registry.get_type_for_model(ReporterModel) # == Reporter
|
global_registry.get_unique_type_for_model(ReporterModel) # == Reporter
|
||||||
|
|
||||||
|
|
||||||
Multiple types for one model
|
Multiple types for one model
|
||||||
|
|
|
@ -126,7 +126,7 @@ def convert_onetoone_field_to_djangomodel(field, registry=None):
|
||||||
model = get_related_model(field)
|
model = get_related_model(field)
|
||||||
|
|
||||||
def dynamic_type():
|
def dynamic_type():
|
||||||
_type = registry.get_type_for_model(model)
|
_type = registry.get_unique_type_for_model(model)
|
||||||
if not _type:
|
if not _type:
|
||||||
return
|
return
|
||||||
|
|
||||||
|
@ -145,7 +145,7 @@ def convert_field_to_list_or_connection(field, registry=None):
|
||||||
model = get_related_model(field)
|
model = get_related_model(field)
|
||||||
|
|
||||||
def dynamic_type():
|
def dynamic_type():
|
||||||
_type = registry.get_type_for_model(model)
|
_type = registry.get_unique_type_for_model(model)
|
||||||
if not _type:
|
if not _type:
|
||||||
return
|
return
|
||||||
|
|
||||||
|
@ -163,7 +163,7 @@ def convert_relatedfield_to_djangomodel(field, registry=None):
|
||||||
model = field.model
|
model = field.model
|
||||||
|
|
||||||
def dynamic_type():
|
def dynamic_type():
|
||||||
_type = registry.get_type_for_model(model)
|
_type = registry.get_unique_type_for_model(model)
|
||||||
if not _type:
|
if not _type:
|
||||||
return
|
return
|
||||||
|
|
||||||
|
@ -183,7 +183,7 @@ def convert_field_to_djangomodel(field, registry=None):
|
||||||
model = get_related_model(field)
|
model = get_related_model(field)
|
||||||
|
|
||||||
def dynamic_type():
|
def dynamic_type():
|
||||||
_type = registry.get_type_for_model(model)
|
_type = registry.get_unique_type_for_model(model)
|
||||||
if not _type:
|
if not _type:
|
||||||
return
|
return
|
||||||
|
|
||||||
|
|
|
@ -1,30 +1,40 @@
|
||||||
|
from collections import defaultdict
|
||||||
|
|
||||||
|
|
||||||
class Registry(object):
|
class Registry(object):
|
||||||
|
|
||||||
def __init__(self):
|
def __init__(self):
|
||||||
self._registry = {}
|
self._registry = defaultdict(list)
|
||||||
self._registry_models = {}
|
|
||||||
|
|
||||||
def register(self, cls):
|
def register(self, cls):
|
||||||
from .types import DjangoObjectType
|
from .types import DjangoObjectType
|
||||||
model = cls._meta.model
|
model = cls._meta.model
|
||||||
assert self._registry.get(model, cls) == cls, (
|
|
||||||
'Django Model "{}.{}" already associated with {}. '
|
|
||||||
'You can use a different registry for {} or skip '
|
|
||||||
'the global Registry with "{}.Meta.skip_global_registry = True".'
|
|
||||||
).format(
|
|
||||||
model._meta.app_label,
|
|
||||||
model._meta.object_name,
|
|
||||||
repr(self.get_type_for_model(cls._meta.model)),
|
|
||||||
repr(cls),
|
|
||||||
cls
|
|
||||||
)
|
|
||||||
assert issubclass(
|
assert issubclass(
|
||||||
cls, DjangoObjectType), 'Only DjangoObjectTypes can be registered, received "{}"'.format(
|
cls, DjangoObjectType), 'Only DjangoObjectTypes can be registered, received "{}"'.format(
|
||||||
cls.__name__)
|
cls.__name__)
|
||||||
assert cls._meta.registry == self, 'Registry for a Model have to match.'
|
assert cls._meta.registry == self, 'Registry for a Model have to match.'
|
||||||
self._registry[cls._meta.model] = cls
|
self._registry[model].append(cls)
|
||||||
|
|
||||||
def get_type_for_model(self, model):
|
def get_unique_type_for_model(self, model):
|
||||||
|
types = self.get_types_for_model(model)
|
||||||
|
if not types:
|
||||||
|
return None
|
||||||
|
|
||||||
|
# If there is more than one type for the model, we should
|
||||||
|
# raise an error so both types don't collide in the same schema.
|
||||||
|
assert len(types) == 1, (
|
||||||
|
'Found multiple ObjectTypes associated with the same Django Model "{}.{}": {}. '
|
||||||
|
'You can use a different registry for each or skip '
|
||||||
|
'the global Registry with Meta.skip_global_registry = True". '
|
||||||
|
'Read more at http://docs.graphene-python.org/projects/django/en/latest/registry/ .'
|
||||||
|
).format(
|
||||||
|
model._meta.app_label,
|
||||||
|
model._meta.object_name,
|
||||||
|
repr(types),
|
||||||
|
)
|
||||||
|
return types[0]
|
||||||
|
|
||||||
|
def get_types_for_model(self, model):
|
||||||
return self._registry.get(model)
|
return self._registry.get(model)
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -18,29 +18,34 @@ def test_registry_basic():
|
||||||
model = ReporterModel
|
model = ReporterModel
|
||||||
|
|
||||||
assert Reporter._meta.registry == global_registry
|
assert Reporter._meta.registry == global_registry
|
||||||
assert global_registry.get_type_for_model(ReporterModel) == Reporter
|
assert global_registry.get_unique_type_for_model(ReporterModel) == Reporter
|
||||||
|
|
||||||
|
|
||||||
def test_registry_multiple_types():
|
def test_registry_multiple_types():
|
||||||
|
global_registry = get_global_registry()
|
||||||
|
|
||||||
class Reporter(DjangoObjectType):
|
class Reporter(DjangoObjectType):
|
||||||
'''Reporter description'''
|
'''Reporter description'''
|
||||||
class Meta:
|
class Meta:
|
||||||
model = ReporterModel
|
model = ReporterModel
|
||||||
|
|
||||||
class Reporter2(object):
|
class Reporter2(DjangoObjectType):
|
||||||
pass
|
'''Reporter2 description'''
|
||||||
|
class Meta:
|
||||||
|
model = ReporterModel
|
||||||
|
|
||||||
|
assert global_registry.get_types_for_model(ReporterModel) == [Reporter, Reporter2]
|
||||||
|
|
||||||
with raises(Exception) as exc_info:
|
with raises(Exception) as exc_info:
|
||||||
class Reporter2(DjangoObjectType):
|
global_registry.get_unique_type_for_model(ReporterModel) == [Reporter, Reporter2]
|
||||||
'''Reporter2 description'''
|
|
||||||
class Meta:
|
|
||||||
model = ReporterModel
|
|
||||||
|
|
||||||
assert str(exc_info.value) == (
|
assert str(exc_info.value) == (
|
||||||
'Django Model "tests.Reporter" already associated with {}. '
|
'Found multiple ObjectTypes associated with the same '
|
||||||
'You can use a different registry for {} '
|
'Django Model "tests.Reporter": {}. You can use a different '
|
||||||
'or skip the global Registry with "Reporter2.Meta.skip_global_registry = True".'
|
'registry for each or skip the global Registry with '
|
||||||
).format(repr(Reporter), repr(Reporter2))
|
'Meta.skip_global_registry = True". '
|
||||||
|
'Read more at http://docs.graphene-python.org/projects/django/en/latest/registry/ .'
|
||||||
|
).format(repr([Reporter, Reporter2]))
|
||||||
|
|
||||||
|
|
||||||
def test_registry_multiple_types_dont_collision_if_skip_global_registry():
|
def test_registry_multiple_types_dont_collision_if_skip_global_registry():
|
||||||
|
|
Loading…
Reference in New Issue
Block a user