fix: ModelSchema doesn't apply alias_generator to foreign key fields - #1747
fix: ModelSchema doesn't apply alias_generator to foreign key fields#1747shivanij1203 wants to merge 2 commits into
Conversation
A foreign key's generated _id field sets its alias explicitly, which bypasses the schema's alias_generator, so it stays snake_case while every other field is transformed (e.g. to camelCase). Apply the generator to the relation attname so the id field is aliased consistently. Closes vitalik#1691.
mbaragiola
left a comment
There was a problem hiding this comment.
Blocker
ninja/orm/fields.py:122:AliasGeneratorsupports independentalias,validation_alias, andserialization_aliascallbacks, but_apply_alias_generator()consults only.alias. If.aliasis unset—for example,AliasGenerator(validation_alias=to_camel, serialization_alias=to_pascal)—the foreign-key field keepstarget_idfor both directions while ordinary fields receive their configured aliases. Please generate and assign the validation and serialization aliases independently, and add runtime validation plusmodel_dump(by_alias=True)coverage rather than checking only field metadata.
Positives
- The common callable
alias_generator=to_camelcase is addressed. - The test compares the foreign-key alias with an ordinary generated field.
Verification
I reviewed the factory/field path and Pydantic’s AliasGenerator.generate_aliases() behavior. GitHub currently reports no checks for this head; I did not run the project suite locally.
Reviewed by Hermes Agent using Codex gpt-5.6-sol.
AliasGenerator can set alias, validation_alias and serialization_alias independently, but the fk _id field only consulted .alias, so a generator without a plain .alias left the field snake_case in both directions while ordinary fields were aliased. Generate and assign each direction separately, falling back to the _id attname where the generator leaves a direction unset.
|
Good catch, thanks. Reworked this so the For the Also swapped the test from metadata-only checks to a behavioral one: it validates via the camelCase validation alias ( |
Summary
When a
ModelSchemasets analias_generator(e.g.to_camel), regular fields are aliased but a foreign key's generated_idfield is not — it stays snake_case while everything else is transformed:{ "id": "...", "model_a_id": ..., // stays snake_case "myOtherProperty": "..." // camelCased }The reason is that relation fields set their alias explicitly (to the
_idattname) inget_schema_field. In pydantic v2 an explicit alias takes precedence over the model'salias_generator, so the generator never runs on the id field.The fix threads the schema's
alias_generator(from the base class'model_config) into relation-field construction and applies it to the attname, so the id field is aliased consistently with the rest of the schema. When no generator is configured, behavior is unchanged (model_a_id).Fixes #1691
Changes
ninja/orm/fields.py:get_schema_fieldaccepts an optionalalias_generatorand applies it to a relation's_idattname (supports a plain callable andAliasGenerator).ninja/orm/factory.py: readalias_generatorfrom the base class'model_configand pass it through when building fields.tests/test_orm_relations.py: regression test asserting a FK's id field is camelCased like other fields.Testing
pytest tests/test_orm_relations.py tests/test_orm_metaclass.py tests/test_models.pypasses.main(the FK alias istarget_idinstead oftargetId) and passes with the fix.ruff format --check,ruff check, andmypy ninjaare all clean.