-
Notifications
You must be signed in to change notification settings - Fork 769
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
Merge fields used in meta attribute passed on DjangoObjectType #1132
base: main
Are you sure you want to change the base?
Conversation
a29b48d
to
aed2f78
Compare
@zbyte64 I added the test cases. Please let me know if it is ok |
If anyone is curious to see an example on real case scenario, let me exemplify with Parler. Django Parler have a functionality that adds all the translated fields into the main Model. In this case we can access directly the translated fields from the main model. However, those fields are not part of the main Meta class and therefore DjangoObjectType does not recognise them. In the example below I'm injecting Django Parler fields in a custom class DjangoParlerObjectType(DjangoObjectType):
class Meta:
abstract = True
@classmethod
def __init_subclass_with_meta__(cls, model=None, _meta=None, registry=None, convert_choices_to_enum=True, **options):
assert is_valid_django_model(model), (
'You need to pass a valid Django Model in {}.Meta, received "{}".'
).format(cls.__name__, model)
if hasattr(model, '_parler_meta'):
if not _meta:
_meta = DjangoObjectTypeOptions(cls)
if not registry:
registry = get_global_registry()
fields = OrderedDict()
for name, parler_model in model._parler_meta.get_fields_with_model():
field = parler_model._meta.get_field(name)
field.null = field.null or field.blank
_convert_choices_to_enum = convert_choices_to_enum
if not isinstance(_convert_choices_to_enum, bool):
if name in _convert_choices_to_enum:
_convert_choices_to_enum = True
else:
_convert_choices_to_enum = False
converted = convert_django_field_with_choices(
field, registry, convert_choices_to_enum=_convert_choices_to_enum
)
fields[name] = converted
parler_fields = yank_fields_from_attrs(
fields,
_as=Field,
)
_meta.fields = parler_fields
super().__init_subclass_with_meta__(model=model, _meta=_meta, registry=registry, convert_choices_to_enum=convert_choices_to_enum, **options) |
graphene_django/tests/test_query.py
Outdated
|
||
@classmethod | ||
def __init_subclass_with_meta__(cls, **options): | ||
options.setdefault("_meta", ArticleTypeOptions(cls)) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I wonder if this is the intended way to override _meta
and why it can't be part of ArticleBaseType.Meta
.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actually after implementing my option for Parler. Probably I can modify this test. Basically in the __init_subclass_with_meta__
we can inject more fields that are part of the model but are not part of the Meta fields of the Django model.
You can see the real life example I put in the comments. I can modify this example to match that one.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@zbyte64 I updated the test with a more realistic scenario. Please let me know what do you think :)
@sebsasto updates? |
Currently I'm working on an integration with Django Parler that require to subclass
DjangoObjectType
to pass the translated fields into the original model. However I cannot do this because the_meta.fields
gets overwritten in the__init_subclass_with_meta__
.This PR allows to pass fields in the
_meta
attribute and merge them with the other fields. This is the same behaviour of the__init_subclass_with_meta__
insideObjectType