def convert_local_fields(model, convertable_fields): """ Converts user-specified model fields as if they were nullable. Also transforms ID to integer field, since it is (usually) an integer. """ # define how each field shall be converted field_conversions = { django.db.models.fields.AutoField: django.db.models.IntegerField } fields = [[name, deepcopy(field)] for name, field in get_local_fields(model)] for i in range(len(fields)): # change a field's type if necessary new_field = field_conversions.get(fields[i][1].__class__, None) if new_field is not None: fields[i][1] = new_field() # set all fields as nullable fields[i][1].null = True # convert the fields ret = OrderedDict() for name, field in fields: if name not in convertable_fields: continue converted = convert_django_field_with_choices(field, get_global_registry()) ret[name] = converted return ret
def __init_subclass_with_meta__( cls, model=None, registry=None, skip_registry=False, only_fields=(), exclude_fields=(), include_fields=(), filter_fields=None, interfaces=(), filterset_class=None, **options, ): assert is_valid_django_model(model), ( 'You need to pass a valid Django Model in {}.Meta, received "{}".' ).format(cls.__name__, model) if not registry: registry = get_global_registry() assert isinstance(registry, Registry), ( "The attribute registry in {} needs to be an instance of " 'Registry, received "{}".').format(cls.__name__, registry) if not DJANGO_FILTER_INSTALLED and (filter_fields or filterset_class): raise Exception( "Can only set filter_fields or filterset_class if Django-Filter is installed" ) django_fields = yank_fields_from_attrs( construct_fields(model, registry, only_fields, include_fields, exclude_fields), _as=Field, ) _meta = DjangoObjectOptions(cls) _meta.model = model _meta.registry = registry _meta.filter_fields = filter_fields _meta.fields = django_fields _meta.filterset_class = filterset_class super(DjangoObjectType, cls).__init_subclass_with_meta__(_meta=_meta, interfaces=interfaces, **options) if not skip_registry: registry.register(cls)
def __init_subclass_with_meta__( cls, model=None, registry=None, results_field_name=None, pagination=None, only_fields=(), exclude_fields=(), filter_fields=None, queryset=None, filterset_class=None, **options, ): assert is_valid_django_model(model), ( 'You need to pass a valid Django Model in {}.Meta, received "{}".' ).format(cls.__name__, model) assert pagination is None, ( 'Pagination should be applied on the ListField enclosing {0} rather than its `{0}.Meta`.' ).format(cls.__name__) if not DJANGO_FILTER_INSTALLED and filter_fields: raise Exception( "Can only set filter_fields if Django-Filter is installed") assert isinstance(queryset, QuerySet) or queryset is None, ( "The attribute queryset in {} needs to be an instance of " 'Django model queryset, received "{}".').format( cls.__name__, queryset) results_field_name = results_field_name or "results" baseType = get_global_registry().get_type_for_model(model) if not baseType: factory_kwargs = { "model": model, "only_fields": only_fields, "exclude_fields": exclude_fields, "filter_fields": filter_fields, "filterset_class": filterset_class, "pagination": pagination, "queryset": queryset, "registry": registry, "skip_registry": False, } baseType = factory_type("output", DjangoObjectType, **factory_kwargs) filter_fields = filter_fields or baseType._meta.filter_fields """ if pagination: result_container = pagination.get_pagination_field(baseType) else: global_paginator = graphql_api_settings.DEFAULT_PAGINATION_CLASS if global_paginator: assert issubclass(global_paginator, BaseDjangoGraphqlPagination), ( 'You need to pass a valid DjangoGraphqlPagination class in {}.Meta, received "{}".' ).format(cls.__name__, global_paginator) global_paginator = global_paginator() result_container = global_paginator.get_pagination_field(baseType) else: """ result_container = CustomDjangoListField(baseType) _meta = DjangoObjectOptions(cls) _meta.model = model _meta.queryset = queryset _meta.baseType = baseType _meta.results_field_name = results_field_name _meta.filter_fields = filter_fields _meta.exclude_fields = exclude_fields _meta.only_fields = only_fields _meta.filterset_class = filterset_class _meta.fields = OrderedDict([ (results_field_name, result_container), ( "count", Field( Int, name="totalCount", description="Total count of matches elements", ), ), ( "page", Field( Int, name="page", description="Page Number", ), ), ( "pageSize", Field( Int, name="pageSize", description="Page Size", ), ) ]) super(DjangoListObjectType, cls).__init_subclass_with_meta__(_meta=_meta, **options)
""" Field definitions for graphene_django_optimizedextras """ from functools import partial from graphene.utils.str_converters import to_snake_case from graphene_django.utils import maybe_queryset, is_valid_django_model from graphene_django_extras.registry import get_global_registry from graphene_django_extras.utils import get_extra_filters from graphene_django_extras.base_types import DjangoListObjectBase from graphene_django_extras.fields import DjangoFilterPaginateListField, DjangoListObjectField from graphene_django_extras.paginations.utils import _get_count from .utils import queryset_factory, get_prefetched_attr registry = get_global_registry() class OptimizedDjangoFilterPaginateListField(DjangoFilterPaginateListField): """ Adds intelligent optimization to the graphene_django_extra's DjangoFilterPaginateListField """ def get_queryset(self, root, field_name, field_asts, fragments, **kwargs): prefetched = get_prefetched_attr(root, to_snake_case(field_name)) if prefetched: print('Using prefetched', field_name) return prefetched filter_kwargs = { k: v for k, v in kwargs.items() if k in self.filtering_args } qs = queryset_factory(self.type.of_type, field_asts, fragments, **kwargs) qs = self.filterset_class(data=filter_kwargs, queryset=qs).qs
def __init_subclass_with_meta__( cls, serializer_class=None, only_fields=(), include_fields=(), exclude_fields=(), input_field_name=None, output_field_name=None, description="", nested_fields=(), **options, ): if not serializer_class: raise Exception( "serializer_class is required on all DjangoSerializerMutation") model = serializer_class.Meta.model description = description or "SerializerMutation for {} model".format( model.__name__) input_field_name = input_field_name or "new_{}".format( model._meta.model_name) output_field_name = output_field_name or model._meta.model_name input_class = getattr(cls, "Arguments", None) if not input_class: input_class = getattr(cls, "Input", None) if input_class: warn_deprecation(( "Please use {name}.Arguments instead of {name}.Input." "Input is now only used in ClientMutationID.\nRead more: " "https://github.com/graphql-python/graphene/blob/2.0/UPGRADE-v2.0.md#mutation-input" ).format(name=cls.__name__)) if input_class: arguments = props(input_class) else: arguments = {} registry = get_global_registry() factory_kwargs = { "model": model, "only_fields": only_fields, "include_fields": include_fields, "exclude_fields": exclude_fields, "nested_fields": nested_fields, "registry": registry, "skip_registry": False, } output_type = registry.get_type_for_model(model) if not output_type: output_type = factory_type("output", DjangoObjectType, **factory_kwargs) django_fields = OrderedDict({output_field_name: Field(output_type)}) global_arguments = {} for operation in ("create", "delete", "update"): global_arguments.update({operation: OrderedDict()}) if operation != "delete": input_type = registry.get_type_for_model(model, for_input=operation) if not input_type: # factory_kwargs.update({'skip_registry': True}) input_type = factory_type("input", DjangoInputObjectType, operation, **factory_kwargs) global_arguments[operation].update( {input_field_name: Argument(input_type, required=True)}) else: global_arguments[operation].update({ "id": Argument( ID, required=True, description="Django object unique identification field", ) }) global_arguments[operation].update(arguments) _meta = SerializerMutationOptions(cls) _meta.output = cls _meta.arguments = global_arguments _meta.fields = django_fields _meta.output_type = output_type _meta.model = model _meta.serializer_class = serializer_class _meta.input_field_name = input_field_name _meta.output_field_name = output_field_name _meta.nested_fields = nested_fields super(DjangoSerializerMutation, cls).__init_subclass_with_meta__(_meta=_meta, description=description, **options)
def __init_subclass_with_meta__( cls, model=None, container=None, registry=None, skip_registry=False, connection=None, use_connection=None, only_fields=(), exclude_fields=(), filter_fields=None, input_for="create", nested_fields=(), **options, ): assert is_valid_django_model(model), ( 'You need to pass a valid Django Model in {}.Meta, received "{}".' ).format(cls.__name__, model) if not registry: registry = get_global_registry() assert isinstance(registry, Registry), ( "The attribute registry in {} needs to be an instance of " 'Registry, received "{}".').format(cls.__name__, registry) assert input_for.lower not in ("create", "delete", "update"), ( 'You need to pass a valid input_for value in {}.Meta, received "{}".' ).format(cls.__name__, input_for) input_for = input_for.lower() if not DJANGO_FILTER_INSTALLED and filter_fields: raise Exception( "Can only set filter_fields if Django-Filter is installed") django_input_fields = yank_fields_from_attrs( construct_fields( model, registry, only_fields, None, exclude_fields, input_for, nested_fields, ), _as=InputField, sort=False, ) for base in reversed(cls.__mro__): django_input_fields.update( yank_fields_from_attrs(base.__dict__, _as=InputField)) if container is None: container = type(cls.__name__, (InputObjectTypeContainer, cls), {}) _meta = DjangoObjectOptions(cls) _meta.by_polar = True _meta.model = model _meta.registry = registry _meta.filter_fields = filter_fields _meta.fields = django_input_fields _meta.input_fields = django_input_fields _meta.connection = connection _meta.input_for = input_for _meta.container = container super(InputObjectType, cls).__init_subclass_with_meta__( # container=container, _meta=_meta, **options, ) if not skip_registry: registry.register(cls, for_input=input_for)