mirror of
https://github.com/graphql-python/graphene-django.git
synced 2025-12-07 10:14:21 +03:00
210 lines
6.0 KiB
Python
210 lines
6.0 KiB
Python
from django.db import models
|
|
from django.utils.encoding import force_text
|
|
from neomodel import (
|
|
AliasProperty,
|
|
ArrayProperty,
|
|
BooleanProperty,
|
|
DateProperty,
|
|
DateTimeProperty,
|
|
EmailProperty,
|
|
FloatProperty,
|
|
IntegerProperty,
|
|
JSONProperty,
|
|
RegexProperty,
|
|
StringProperty,
|
|
UniqueIdProperty,
|
|
ZeroOrMore,
|
|
ZeroOrOne,
|
|
One,
|
|
OneOrMore,
|
|
)
|
|
|
|
from neomodel.relationship_manager import RelationshipDefinition
|
|
|
|
try:
|
|
# TimurMardanov fork branch. Supports contain 2D-xD arrays
|
|
from neomodel import JsonArrayProperty # noqa
|
|
jsonArrayProperty = JsonArrayProperty
|
|
except BaseException:
|
|
jsonArrayProperty = JSONProperty
|
|
|
|
from graphene import (
|
|
ID,
|
|
Boolean,
|
|
Dynamic,
|
|
Enum,
|
|
Field,
|
|
Float,
|
|
Int,
|
|
List,
|
|
NonNull,
|
|
String,
|
|
UUID,
|
|
DateTime,
|
|
Date,
|
|
Time,
|
|
)
|
|
from graphene.types.json import JSONString
|
|
from graphene.utils.str_converters import to_camel_case, to_const
|
|
from graphql import assert_valid_name
|
|
|
|
from .compat import ArrayField, HStoreField, JSONField, RangeField
|
|
from .fields import DjangoListField, DjangoConnectionField
|
|
from .utils import import_single_dispatch
|
|
|
|
singledispatch = import_single_dispatch()
|
|
|
|
|
|
REQUIRED_CARDINALITY = (One, OneOrMore, )
|
|
NOT_REQUIRED_CARDINALITY = (ZeroOrMore, ZeroOrOne,)
|
|
|
|
|
|
@singledispatch
|
|
def define_null_parameter(manager):
|
|
raise Exception(
|
|
"Don't know how to convert the Neomodel relationship field"
|
|
)
|
|
|
|
|
|
@define_null_parameter.register(REQUIRED_CARDINALITY[0])
|
|
@define_null_parameter.register(REQUIRED_CARDINALITY[1])
|
|
def return_required(field):
|
|
return True
|
|
|
|
|
|
@define_null_parameter.register(NOT_REQUIRED_CARDINALITY[0])
|
|
@define_null_parameter.register(NOT_REQUIRED_CARDINALITY[1])
|
|
def return_required(field):
|
|
return False
|
|
|
|
|
|
def convert_choice_name(name):
|
|
name = to_const(force_text(name))
|
|
try:
|
|
assert_valid_name(name)
|
|
except AssertionError:
|
|
name = "A_%s" % name
|
|
return name
|
|
|
|
|
|
def get_choices(choices):
|
|
converted_names = []
|
|
for value, help_text in choices.items():
|
|
if isinstance(help_text, (tuple, list)):
|
|
for choice in get_choices(help_text):
|
|
yield choice
|
|
else:
|
|
name = convert_choice_name(value)
|
|
while name in converted_names:
|
|
name += "_" + str(len(converted_names))
|
|
converted_names.append(name)
|
|
description = help_text
|
|
yield name, value, description
|
|
|
|
|
|
def convert_django_field_with_choices(field, registry=None):
|
|
if registry is not None:
|
|
converted = registry.get_converted_field(field)
|
|
if converted:
|
|
return converted
|
|
choices = getattr(field, "choices", None)
|
|
if choices:
|
|
field_class = field.owner
|
|
name = to_camel_case("{}_{}".format(field_class.__name__, field.name))
|
|
choices = list(get_choices(dict(choices)))
|
|
named_choices = [(c[0], c[1]) for c in choices]
|
|
named_choices_descriptions = {c[0]: c[2] for c in choices}
|
|
|
|
class EnumWithDescriptionsType(object):
|
|
@property
|
|
def description(self):
|
|
return named_choices_descriptions[self.name]
|
|
|
|
enum = Enum(name, list(named_choices), type=EnumWithDescriptionsType)
|
|
converted = enum(description=field.help_text, required=field.required)
|
|
else:
|
|
converted = convert_django_field(field, registry)
|
|
if registry is not None:
|
|
registry.register_converted_field(field, converted)
|
|
return converted
|
|
|
|
|
|
@singledispatch
|
|
def convert_django_field(field, registry=None):
|
|
raise Exception(
|
|
"Don't know how to convert the Django field %s (%s)" % (field, field.__class__)
|
|
)
|
|
|
|
|
|
@convert_django_field.register(StringProperty)
|
|
@convert_django_field.register(RegexProperty)
|
|
def convert_field_to_string(field, registry=None):
|
|
return String(description=field.help_text)
|
|
|
|
|
|
@convert_django_field.register(IntegerProperty)
|
|
def convert_field_to_int(field, registry=None):
|
|
return Int(description=field.help_text)
|
|
|
|
|
|
@convert_django_field.register(BooleanProperty)
|
|
def convert_field_to_boolean(field, registry=None):
|
|
return NonNull(Boolean, description=field.help_text)
|
|
|
|
|
|
@convert_django_field.register(FloatProperty)
|
|
def convert_field_to_float(field, registry=None):
|
|
return Float(description=field.help_text)
|
|
|
|
|
|
@convert_django_field.register(DateTimeProperty)
|
|
def convert_datetime_to_string(field, registry=None):
|
|
return DateTime(description=field.help_text)
|
|
|
|
|
|
@convert_django_field.register(DateProperty)
|
|
def convert_date_to_string(field, registry=None):
|
|
return Date(description=field.help_text)
|
|
|
|
|
|
@convert_django_field.register(RelationshipDefinition)
|
|
def convert_onetoone_field_to_djangomodel(field, registry=None):
|
|
model = field._raw_class
|
|
manager = field.build_manager(model, 'field')
|
|
|
|
def dynamic_type():
|
|
_type = registry.get_type_for_model(manager.definition['node_class'])
|
|
if not _type:
|
|
return
|
|
|
|
if _type._meta.connection:
|
|
# Use a DjangoFilterConnectionField if there are
|
|
# defined filter_fields in the DjangoObjectType Meta
|
|
if _type._meta.neomodel_filter_fields:
|
|
from .filter.fields import DjangoFilterConnectionField # noqa
|
|
return DjangoFilterConnectionField(_type)
|
|
return DjangoConnectionField(_type)
|
|
return DjangoListField(_type)
|
|
|
|
return Dynamic(dynamic_type)
|
|
|
|
|
|
@convert_django_field.register(ArrayProperty)
|
|
def convert_array_to_list(field, registry=None):
|
|
base_property = field.base_property or StringProperty()
|
|
return List(description=field.help_text,
|
|
of_type=convert_django_field(base_property).__class__)
|
|
|
|
# @singledispatch
|
|
# def define_base_property(base_property):
|
|
# raise Exception("This property not implemented yet")
|
|
|
|
# @convert_array_to_list.register()
|
|
# def check_base_property_integer
|
|
|
|
|
|
@convert_django_field.register(JSONProperty)
|
|
@convert_django_field.register(jsonArrayProperty)
|
|
def convert_json_field_to_string(field, registry=None):
|
|
return JSONString(description=field.help_text)
|