Skip to content

fix: create_schema crashes on models with a ForeignObject reverse relation - #1746

Open
shivanij1203 wants to merge 1 commit into
vitalik:masterfrom
shivanij1203:fix/foreignobject-reverse-relation
Open

fix: create_schema crashes on models with a ForeignObject reverse relation#1746
shivanij1203 wants to merge 1 commit into
vitalik:masterfrom
shivanij1203:fix/foreignobject-reverse-relation

Conversation

@shivanij1203

Copy link
Copy Markdown

Summary

Generating a ModelSchema / calling create_schema() for a model that is the target of a ForeignObject relation crashes with:

AttributeError: 'ForeignObjectRel' object has no attribute 'help_text'

SchemaFactory._model_fields skips reverse relations, but it only checked for ManyToOneRel and ManyToManyRel. A ForeignObject field creates a bare ForeignObjectRel (the base class of those two) on the target model, so it fell through the filter and reached field.help_text in get_schema_field, which a reverse relation does not have.

Since ManyToOneRel and ManyToManyRel both subclass ForeignObjectRel, filtering on the base class covers every reverse relation, including the bare ForeignObjectRel.

Fixes #1530

Changes

  • ninja/orm/factory.py: skip ForeignObjectRel (the reverse-relation base class) instead of only its two subclasses. This also let the now-redundant cast(DjangoField, fld) be removed, since fld is narrowed to Field after the check.
  • tests/test_orm_relations.py: regression test using isolate_apps so the reverse ForeignObjectRel actually registers.

Testing

  • pytest tests/test_orm_relations.py tests/test_orm_metaclass.py tests/test_models.py tests/test_django_models.py passes.
  • The new test fails against main with the exact AttributeError: 'ForeignObjectRel' object has no attribute 'help_text', and passes with the fix.
  • ruff format --check, ruff check, and mypy ninja/orm/factory.py are clean.

Minimal reproduction (from the issue): a model OrderDetail with models.ForeignObject(Order, ..., related_name="details"), then create_schema(Order).

…ation

The field filter only skipped ManyToOneRel and ManyToManyRel, so the bare ForeignObjectRel that a ForeignObject field creates on the target model fell through and hit .help_text, which it does not have. Skip the ForeignObjectRel base class instead, which covers every reverse relation. Closes vitalik#1530.

@mbaragiola mbaragiola left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Positives

  • Generalizing the reverse-relation filter to ForeignObjectRel covers the bare reverse object while retaining the existing ManyToOneRel and ManyToManyRel behavior through inheritance.
  • The regression test reproduces the crashing relation shape, verifies schema creation, and checks that the reverse accessor is excluded while normal fields remain.

Residual risk

  • The new test covers the default depth path only, although the shared field-selection path makes a depth-specific regression unlikely.

Verification

I reviewed the relation hierarchy, schema field-selection path, and regression test against master. GitHub currently reports no checks for this head; I did not run the test suite locally.

Reviewed by Hermes Agent using Codex gpt-5.6-sol.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Django Ninja fails with ForeignObject fields: AttributeError 'ForeignObjectRel' object has no attribute 'help_text'

2 participants