def _get_fields(model, only_fields, exclude_fields, required_fields): fields = [ (field.name, field) for field in sorted(list(model._meta.fields + model._meta.many_to_many)) ] # Only add the field as input field if the foreign key (reverse side) # can be set to null, otherwise updates won't work. fields.extend([ (field.related_name or field.name + "_set", field) for field in sorted( list(model._meta.related_objects), key=lambda field: field.name, ) if not isinstance(field, ManyToOneRel) or field.remote_field.null ], ) ret = collections.OrderedDict() for name, field in fields: if ((only_fields and name not in only_fields) or name in exclude_fields or str(name).endswith('+') or name in ['created_at', 'updated_at', 'archived_at']): continue if name == 'id': ret[name] = graphene.ID(description="The ID of the object.", ) elif isinstance(field, models.FileField): ret[name] = UploadType(description=field.help_text, ) elif isinstance(field, models.BooleanField): ret[name] = graphene.Boolean(description=field.help_text, ) elif isinstance(field, (models.ForeignKey, models.OneToOneField)): ret[name] = graphene.ID(description=field.help_text, ) elif isinstance(field, models.ManyToManyField): ret[name] = graphene.List( graphene.ID, description=field.help_text, ) elif isinstance(field, (ManyToOneRel, ManyToManyRel)): reverse_rel_include = graphene_django_plus_settings.MUTATIONS_INCLUDE_REVERSE_RELATIONS # Checking whether it was globally configured to not include reverse relations if isinstance(field, ManyToOneRel ) and not reverse_rel_include and not only_fields: continue ret[name] = graphene.List( graphene.ID, description='Set list of {0}'.format( field.related_model._meta.verbose_name_plural, ), ) else: ret[name] = convert_django_field_with_choices(field, _registry) if required_fields is not None: ret[name].kwargs['required'] = name in required_fields else: if isinstance(field, (ManyToOneRel, ManyToManyRel)): ret[name].kwargs['required'] = not field.null else: ret[name].kwargs['required'] = not field.blank return ret
def get_input_field( field: Union[Field, ForeignObjectRel], registry: Registry ) -> Union[Scalar, Structure]: """Convert a model field into a GraphQL input type used in mutations. :param field: A model field. :param registry: Registry which holds a mapping between django models/fields and Graphene types. :return: A scalar that can be used as an input field in mutations. """ return convert_django_field_with_choices(field, registry)
def convert_serializer_field_to_enum(field): # TODO: could be removed once following issue is fixed # https://github.com/graphql-python/graphene-django/issues/517 model_class = None serializer_meta = getattr(field.parent, "Meta", None) if serializer_meta: model_class = getattr(serializer_meta, "model", None) if model_class: registry = get_global_registry() model_field = model_class._meta.get_field(field.source) return type(convert_django_field_with_choices(model_field, registry)) return graphene.String
def _get_fields(model, only_fields, exclude_fields, required_fields): fields = [ (field.name, field) for field in sorted(list(model._meta.fields + model._meta.many_to_many)) ] ret = collections.OrderedDict() for name, field in fields: if ((only_fields and name not in only_fields) or name in exclude_fields or str(name).endswith('+') or name in ['created_at', 'updated_at', 'archived_at']): continue if name == 'id': ret[name] = graphene.ID(description="The ID of the object.", ) elif isinstance(field, models.FileField): ret[name] = UploadType( description=field.help_text, required=not field.null, ) elif isinstance(field, models.BooleanField): ret[name] = graphene.Boolean( description=field.help_text, required=not field.null and not field.blank, ) elif isinstance(field, (models.ForeignKey, models.OneToOneField)): ret[name] = graphene.ID( description=field.help_text, required=not field.null, ) elif isinstance(field, models.ManyToManyField): ret[name] = graphene.List( graphene.ID, description=field.help_text, required=not field.null, ) else: ret[name] = convert_django_field_with_choices(field, _registry) if required_fields is not None: ret[name].kwargs['required'] = name in required_fields return ret
def _get_fields(model, only_fields, exclude_fields, required_fields): ret = collections.OrderedDict() for name, field in get_model_fields(model): if ( (only_fields and name not in only_fields) or name in exclude_fields or str(name).endswith("+") or name in ["created_at", "updated_at", "archived_at"] ): continue if name == "id": f = graphene.ID( description="The ID of the object.", ) elif isinstance(field, models.FileField): f = UploadType( description=field.help_text, ) elif isinstance(field, models.BooleanField): f = graphene.Boolean( description=field.help_text, ) elif isinstance(field, (models.ForeignKey, models.OneToOneField)): f = graphene.ID( description=field.help_text, ) elif isinstance(field, models.ManyToManyField): f = graphene.List( graphene.ID, description=field.help_text, ) elif isinstance(field, (ManyToOneRel, ManyToManyRel)): reverse_rel_include = graphene_django_plus_settings.MUTATIONS_INCLUDE_REVERSE_RELATIONS # Checking whether it was globally configured to not include reverse relations if isinstance(field, ManyToOneRel) and not reverse_rel_include and not only_fields: continue f = graphene.List( graphene.ID, description="Set list of {0}".format( field.related_model._meta.verbose_name_plural, ), ) else: f = convert_django_field_with_choices(field, _registry) if required_fields is not None: f.kwargs["required"] = name in required_fields else: if isinstance(field, (ManyToOneRel, ManyToManyRel)): f.kwargs["required"] = not field.null else: f.kwargs["required"] = not field.blank and field.default is NOT_PROVIDED s = schema_for_field(field, name) s["validation"]["required"] = f.kwargs["required"] ret[name] = { "field": f, "schema": s, } return ret
def _get_fields(model, only_fields, exclude_fields, required_fields): fields = [ (field.name, field) for field in sorted(list(model._meta.fields + model._meta.many_to_many)) ] # Only add the field as input field if the foreign key (reverse side) # can be set to null, otherwise updates won't work. fields.extend([ (field.related_name or field.name + "_set", field) for field in sorted( list(model._meta.related_objects), key=lambda field: field.name, ) if not isinstance(field, ManyToOneRel) or field.remote_field.null ], ) ret = collections.OrderedDict() for name, field in fields: if ((only_fields and name not in only_fields) or name in exclude_fields or str(name).endswith("+") or name in ["created_at", "updated_at", "archived_at"]): continue if name == "id": f = graphene.ID(description="The ID of the object.", ) elif isinstance(field, models.FileField): f = UploadType(description=field.help_text, ) elif isinstance(field, models.BooleanField): f = graphene.Boolean(description=field.help_text, ) elif isinstance(field, (models.ForeignKey, models.OneToOneField)): f = graphene.ID(description=field.help_text, ) elif isinstance(field, models.ManyToManyField): f = graphene.List( graphene.ID, description=field.help_text, ) elif isinstance(field, (ManyToOneRel, ManyToManyRel)): reverse_rel_include = graphene_django_plus_settings.MUTATIONS_INCLUDE_REVERSE_RELATIONS # Checking whether it was globally configured to not include reverse relations if isinstance(field, ManyToOneRel ) and not reverse_rel_include and not only_fields: continue f = graphene.List( graphene.ID, description="Set list of {0}".format( field.related_model._meta.verbose_name_plural, ), ) else: f = convert_django_field_with_choices(field, _registry) if required_fields is not None: f.kwargs["required"] = name in required_fields else: if isinstance(field, (ManyToOneRel, ManyToManyRel)): f.kwargs["required"] = not field.null else: f.kwargs[ "required"] = not field.blank and field.default is NOT_PROVIDED if getattr(field, "choices", None): items = field.choices if isinstance(items, dict): items = items.items() choices = [] for (original_v, label), (n, value, desc) in zip(items, get_choices(items)): choices.append({ "label": label, "name": n, "value": value, }) else: choices = None s = get_field_schema(field) s.update({ "name": name, # FIXME: Get verbose_name and help_text for m2m "label": getattr(field, "verbose_name", None), "help_text": getattr(field, "help_text", None), "max_length": getattr(field, "max_length", None), "choices": choices, }) ret[name] = { "field": f, "schema": s, } return ret