Merge fields used in meta attribute passed on DjangoObjectType
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__ inside ObjectType
@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 DjangoObjectType using the feature introduced in this PR.
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)
@sebsasto updates?