Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Support select operations to build #10

Merged
merged 1 commit into from
Jun 20, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 4 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ When the SessionManager is used, the operations related to authentication are:

This package don't limit to use this basic operations. Custom operations can be defined on classic style of Graphene and Graphene-Django and finally can be merged on the main schema as described on the Quickstart section of this documentation at 4. Create a main schema in a new file called schema.py on my_project folder. This file can be used to merge all queries and mutations from all apps builded with django_graphbox or just add your own queries and mutations.

See the full documentation at <https://90horasporsemana.com/graphbox/>
See the API REFERENCE at <https://90horasporsemana.com/graphbox/>

# Installation

Expand Down Expand Up @@ -447,3 +447,6 @@ Some of the extra features are:
# Release Notes

> - Version 1.0.0 to 1.1.5 was a package developed for a specific project, and the code was not published on GitHub. The code was refactored and published on GitHub on version 1.2.0.
> - Version 1.2.3 add support to set custom attributes on the model Type and set custom ordering field for the queries.
> - Version 1.2.4 Fix custom attributes on the model Type.
> - Version 1.2.5 Add support to select the operations to build for the model. You can select between field_by_id, list_field, create_field, update_field and delete_field operations. By default all operations are selected.
3 changes: 2 additions & 1 deletion docs/source/quickstart.rst
Original file line number Diff line number Diff line change
Expand Up @@ -335,4 +335,5 @@ Release Notes

* Version 1.0.0 to 1.1.5 was a package developed for a specific project, and the code was not published on GitHub. The code was refactored and published on GitHub on version 1.2.0.
* Version 1.2.3 add support to set custom attributes on the model Type and set custom ordering field for the queries.
* Version 1.2.4 Fix custom attributes on the model Type.
* Version 1.2.4 Fix custom attributes on the model Type.
* Version 1.2.5 Add support to select the operations to build for the model. You can select between field_by_id, list_field, create_field, update_field and delete_field operations. By default all operations are selected.
2 changes: 1 addition & 1 deletion setup.cfg
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[metadata]
name = django_graphbox
version = 1.2.5
version = 1.2.6
description = Package for easy building GraphQL API with Django
long_description = file:docs/source/quickstart.rst
url = https://github.com/yefeza/django-graphbox
Expand Down
73 changes: 40 additions & 33 deletions src/django_graphbox/builder.py
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ def __init__(self, session_manager=None):
self._models_by_op_name = {}
self._session_manager = session_manager

def add_model(self, model, exclude_fields=(), pagination_length=0, pagination_style='infinite', external_filters=[], internal_filters=[], filters_opeator=Q.AND, access_group=None, access_by_operation={}, validators_by_operation={}, internal_field_resolvers={}, exclude_fields_by_operation={}, save_as_password=[], callbacks_by_operation={}, custom_attrs_for_type=[], ordering_field='id', **kwargs):
def add_model(self, model, exclude_fields=(), pagination_length=0, pagination_style='infinite', external_filters=[], internal_filters=[], filters_opeator=Q.AND, access_group=None, access_by_operation={}, validators_by_operation={}, internal_field_resolvers={}, exclude_fields_by_operation={}, save_as_password=[], callbacks_by_operation={}, custom_attrs_for_type=[], ordering_field='id', operations_to_build=['field_by_id', 'list_field', 'create_field', 'update_field', 'delete_field'], **kwargs):
"""Add model for build operations.

Args:
Expand All @@ -42,6 +42,7 @@ def add_model(self, model, exclude_fields=(), pagination_length=0, pagination_st
callbacks_by_operation (dict): Dictionary with the callbacks list to use for the access. {'operation': [callable(info, model_instance, **kwargs)], ...}
custom_attrs_for_type (list): List of custom attributes to add to the model type. [{'name': 'attr_name', 'value': 'attr_value'}, ...]
ordering_field (str): Field to use for ordering the list_field operation.
operations_to_build (list): List of operations to build. Possible values are 'field_by_id', 'list_field', 'create_field', 'update_field' and 'delete_field'.
"""
#get the model name
model_name = model.__name__
Expand Down Expand Up @@ -74,7 +75,8 @@ def add_model(self, model, exclude_fields=(), pagination_length=0, pagination_st
'exclude_fields_by_operation': exclude_fields_by_operation,
'save_as_password': save_as_password,
'callbacks_by_operation': callbacks_by_operation,
'ordering_field': ordering_field
'ordering_field': ordering_field,
'operations_to_build': operations_to_build
}
self._models_config[model_name]=config

Expand All @@ -89,16 +91,18 @@ def build_schema_query(self):
model_config=self._models_config[key]
object_name=model_config['name'].lower()
# build field_by_id query
field_by_id_resolver_function=build_field_by_id_resolver(self)
self._models_by_op_name[object_name]=model_config
setattr(query_class, object_name, graphene.Field(model_config['type'], id=graphene.ID(required=True)))
setattr(query_class, f'resolve_{object_name}', field_by_id_resolver_function)
if 'field_by_id' in model_config['operations_to_build']:
field_by_id_resolver_function=build_field_by_id_resolver(self)
self._models_by_op_name[object_name]=model_config
setattr(query_class, object_name, graphene.Field(model_config['type'], id=graphene.ID(required=True)))
setattr(query_class, f'resolve_{object_name}', field_by_id_resolver_function)
# build list_field query
field_list_resolver_function=build_field_list_resolver(self)
self._models_by_op_name['all' + object_name]=model_config
return_object=get_return_object(model_config)
setattr(query_class, f"all_{object_name}", return_object)
setattr(query_class, f'resolve_all_{object_name}',field_list_resolver_function)
if 'list_field' in model_config['operations_to_build']:
field_list_resolver_function=build_field_list_resolver(self)
self._models_by_op_name['all' + object_name]=model_config
return_object=get_return_object(model_config)
setattr(query_class, f"all_{object_name}", return_object)
setattr(query_class, f'resolve_all_{object_name}',field_list_resolver_function)
return query_class

def build_schema_mutation(self):
Expand All @@ -111,30 +115,33 @@ def build_schema_mutation(self):
for key in self._models_config.keys():
model_config=self._models_config[key]
# create the create mutation
mutate_create_function=build_mutate_for_create(self)
# get fields to ignore on arguments
fields_to_ignore=get_fields_to_ignore(model_config, 'create_field')
# build argumants class
arguments_create=create_arguments_class(model_config['model'], fields_to_ignore)
create_mutation=type("Create"+model_config['name'], (graphene.Mutation,), {"estado":graphene.Boolean(),model_config['name'].lower(): graphene.Field(model_config['type']), "error":graphene.Field(ErrorMsgType), 'Arguments': arguments_create, 'mutate': mutate_create_function})
setattr(mutation_class, f"create_{model_config['name'].lower()}", create_mutation.Field())
self._models_by_op_name['create' + model_config['name'].lower()]=model_config
if 'create_field' in model_config['operations_to_build']:
mutate_create_function=build_mutate_for_create(self)
# get fields to ignore on arguments
fields_to_ignore=get_fields_to_ignore(model_config, 'create_field')
# build argumants class
arguments_create=create_arguments_class(model_config['model'], fields_to_ignore)
create_mutation=type("Create"+model_config['name'], (graphene.Mutation,), {"estado":graphene.Boolean(),model_config['name'].lower(): graphene.Field(model_config['type']), "error":graphene.Field(ErrorMsgType), 'Arguments': arguments_create, 'mutate': mutate_create_function})
setattr(mutation_class, f"create_{model_config['name'].lower()}", create_mutation.Field())
self._models_by_op_name['create' + model_config['name'].lower()]=model_config
# create the update mutation
mutate_update_function=build_mutate_for_update(self)
# get fields to omit
fields_to_ignore=get_fields_to_ignore(model_config, 'update_field')
# build argumants class
arguments_update=update_arguments_class(model_config['model'], fields_to_ignore, model_config.get('save_as_password'))
update_mutation=type("Update"+model_config['name'], (graphene.Mutation,), {"estado":graphene.Boolean(),model_config['name'].lower(): graphene.Field(model_config['type']), "error":graphene.Field(ErrorMsgType), 'Arguments': arguments_update, 'mutate': mutate_update_function})
setattr(mutation_class, f"update_{model_config['name'].lower()}", update_mutation.Field())
self._models_by_op_name['update' + model_config['name'].lower()]=model_config
if 'update_field' in model_config['operations_to_build']:
mutate_update_function=build_mutate_for_update(self)
# get fields to omit
fields_to_ignore=get_fields_to_ignore(model_config, 'update_field')
# build argumants class
arguments_update=update_arguments_class(model_config['model'], fields_to_ignore, model_config.get('save_as_password'))
update_mutation=type("Update"+model_config['name'], (graphene.Mutation,), {"estado":graphene.Boolean(),model_config['name'].lower(): graphene.Field(model_config['type']), "error":graphene.Field(ErrorMsgType), 'Arguments': arguments_update, 'mutate': mutate_update_function})
setattr(mutation_class, f"update_{model_config['name'].lower()}", update_mutation.Field())
self._models_by_op_name['update' + model_config['name'].lower()]=model_config
# create the delete mutation
mutate_delete_function=build_mutate_for_delete(self)
# build argumants class
delete_arguments=delete_arguments_class()
delete_mutation=type("Delete"+model_config['name'], (graphene.Mutation,), {"estado":graphene.Boolean(), "error":graphene.Field(ErrorMsgType), 'Arguments': delete_arguments, 'mutate': mutate_delete_function})
setattr(mutation_class, f"delete_{model_config['name'].lower()}", delete_mutation.Field())
self._models_by_op_name['delete' + model_config['name'].lower()]=model_config
if 'delete_field' in model_config['operations_to_build']:
mutate_delete_function=build_mutate_for_delete(self)
# build argumants class
delete_arguments=delete_arguments_class()
delete_mutation=type("Delete"+model_config['name'], (graphene.Mutation,), {"estado":graphene.Boolean(), "error":graphene.Field(ErrorMsgType), 'Arguments': delete_arguments, 'mutate': mutate_delete_function})
setattr(mutation_class, f"delete_{model_config['name'].lower()}", delete_mutation.Field())
self._models_by_op_name['delete' + model_config['name'].lower()]=model_config
return mutation_class

def build_session_schema(self):
Expand Down