[Django] #37060: AlterField doesn't propagate type changes through transitive attname-based to_field references

24 views
Skip to first unread message

Django

unread,
Apr 23, 2026, 5:13:59 AMApr 23
to django-...@googlegroups.com
#37060: AlterField doesn't propagate type changes through transitive attname-based
to_field references
-------------------------------------+-------------------------------------
Reporter: Andrea Zanotto | Type: Bug
Status: new | Component:
| Migrations
Version: 5.2 | Severity: Normal
Keywords: schema alterfield | Triage Stage:
to_field attname foreignkey | Unreviewed
Has patch: 1 | Needs documentation: 0
Needs tests: 0 | Patch needs improvement: 0
Easy pickings: 0 | UI/UX: 0
-------------------------------------+-------------------------------------
When a relation uses an attname-based `to_field` such as `primary_id`,
Django accepts and resolves it correctly, but `AlterField` does not always
propagate type changes through transitive dependencies.

Minimal example:
{{{
class Primary(models.Model):
code = models.CharField(max_length=5, unique=True)

class Related(models.Model):
primary = models.OneToOneField(
Primary,
to_field="code",
on_delete=models.CASCADE,
)

class Dependent(models.Model):
related = models.ForeignKey(
Related,
to_field="primary_id",
on_delete=models.CASCADE,
)
}}}
If `Primary.code.max_length` is changed from 5 to 11, Django correctly
updates `Related.primary_id`, but `Dependent.related_id` remains at
`varchar(5)` instead of widening to `varchar(11)`.
== Behavior
Using:
- `to_field="primary"` works correctly
- `to_field="primary_id"` does not
However, Django currently accepts `primary_id` as a valid `to_field`
reference because relation resolution uses `Options.get_field()`, and
`get_field()` maps both the field name and the relation attname to the
same field object.
That means if `ForeignKey(..., to_field="primary_id")` is accepted and
resolved as valid, schema alteration should handle it the same way as
`to_field="primary"`.
== Cause
The schema dependency walk in `django/db/backends/base/schema.py` uses
`_related_non_m2m_objects()` and `_is_relevant_relation()` to discover
fields whose database type must be updated.
Before the fix, `_is_relevant_relation()` compared only the altered
field's `name` against `field.to_fields`.
In the example above, the recursive step compares:
- altered field name: `primary`
- dependent field `to_fields`: `["primary_id"]`
So the dependency is missed even though both names refer to the same
remote field.
As a result, the transitive dependent column is excluded from schema
propagation.
== Expected behavior
Altering `Primary.code` from `max_length=5` to `max_length=11` should also
widen:
- `Related.primary_id`
- `Dependent.related_id`
regardless of whether the dependent relation was declared with:
- `to_field="primary"`
- `to_field="primary_id"`
== Fix
Treat attname-based `to_field` values as equivalent to the actual remote
field when determining whether a relation depends on the altered field.
In practice, this means resolving each `to_field` through
`remote_model._meta.get_field(...)` and comparing field identity, instead
of only comparing raw field names.
SQLite also needs the same recursive dependency logic in its schema editor
override when rebuilding related tables after altering unique fields.
--
Ticket URL: <https://code.djangoproject.com/ticket/37060>
Django <https://code.djangoproject.com/>
The Web framework for perfectionists with deadlines.

Django

unread,
Apr 23, 2026, 5:31:06 AMApr 23
to django-...@googlegroups.com
#37060: AlterField doesn't propagate type changes through transitive attname-based
to_field references
-------------------------------------+-------------------------------------
Reporter: Andrea Zanotto | Owner: Andrea
| Zanotto
Type: Bug | Status: assigned
Component: Migrations | Version: 5.2
Severity: Normal | Resolution:
Keywords: schema alterfield | Triage Stage:
to_field attname foreignkey | Unreviewed
Has patch: 1 | Needs documentation: 0
Needs tests: 0 | Patch needs improvement: 0
Easy pickings: 0 | UI/UX: 0
-------------------------------------+-------------------------------------
Changes (by Andrea Zanotto):

* owner: (none) => Andrea Zanotto
* status: new => assigned

--
Ticket URL: <https://code.djangoproject.com/ticket/37060#comment:1>

Django

unread,
Apr 29, 2026, 4:38:19 PMApr 29
to django-...@googlegroups.com
#37060: AlterField doesn't propagate type changes through transitive attname-based
to_field references
-------------------------------------+-------------------------------------
Reporter: Andrea Zanotto | Owner: Andrea
| Zanotto
Type: Bug | Status: assigned
Component: Migrations | Version: 5.2
Severity: Normal | Resolution:
Keywords: schema alterfield | Triage Stage: Accepted
to_field attname foreignkey |
Has patch: 1 | Needs documentation: 0
Needs tests: 0 | Patch needs improvement: 0
Easy pickings: 0 | UI/UX: 0
-------------------------------------+-------------------------------------
Changes (by Jacob Walls):

* stage: Unreviewed => Accepted

Comment:

Thanks, reproduced at 3f912ee4189602b4df121c0dc0428673fda5c253.
--
Ticket URL: <https://code.djangoproject.com/ticket/37060#comment:2>

Django

unread,
Apr 29, 2026, 5:28:16 PMApr 29
to django-...@googlegroups.com
#37060: AlterField doesn't propagate type changes through transitive attname-based
to_field references
-------------------------------------+-------------------------------------
Reporter: Andrea Zanotto | Owner: Andrea
| Zanotto
Type: Bug | Status: assigned
Component: Migrations | Version: 5.2
Severity: Normal | Resolution:
Keywords: schema alterfield | Triage Stage: Accepted
to_field attname foreignkey |
Has patch: 1 | Needs documentation: 0
Needs tests: 1 | Patch needs improvement: 0
Easy pickings: 0 | UI/UX: 0
-------------------------------------+-------------------------------------
Changes (by Jacob Walls):

* needs_tests: 0 => 1

--
Ticket URL: <https://code.djangoproject.com/ticket/37060#comment:3>

Django

unread,
May 4, 2026, 1:22:02 PMMay 4
to django-...@googlegroups.com
#37060: AlterField doesn't propagate type changes through transitive attname-based
to_field references
-------------------------------------+-------------------------------------
Reporter: Andrea Zanotto | Owner: Andrea
| Zanotto
Type: Bug | Status: assigned
Component: Migrations | Version: 5.2
Severity: Normal | Resolution:
Keywords: schema alterfield | Triage Stage: Accepted
to_field attname foreignkey |
Has patch: 1 | Needs documentation: 0
Needs tests: 0 | Patch needs improvement: 1
Easy pickings: 0 | UI/UX: 0
-------------------------------------+-------------------------------------
Changes (by Jacob Walls):

* needs_better_patch: 0 => 1
* needs_tests: 1 => 0

--
Ticket URL: <https://code.djangoproject.com/ticket/37060#comment:4>

Django

unread,
May 6, 2026, 10:53:47 AMMay 6
to django-...@googlegroups.com
#37060: AlterField doesn't propagate type changes through transitive attname-based
to_field references
-------------------------------------+-------------------------------------
Reporter: Andrea Zanotto | Owner: Andrea
| Zanotto
Type: Bug | Status: assigned
Component: Migrations | Version: 5.2
Severity: Normal | Resolution:
Keywords: schema alterfield | Triage Stage: Accepted
to_field attname foreignkey |
Has patch: 1 | Needs documentation: 0
Needs tests: 0 | Patch needs improvement: 0
Easy pickings: 0 | UI/UX: 0
-------------------------------------+-------------------------------------
Changes (by Jacob Walls):

* needs_better_patch: 1 => 0

--
Ticket URL: <https://code.djangoproject.com/ticket/37060#comment:5>

Django

unread,
May 6, 2026, 2:39:58 PMMay 6
to django-...@googlegroups.com
#37060: AlterField doesn't propagate type changes through transitive attname-based
to_field references
-------------------------------------+-------------------------------------
Reporter: Andrea Zanotto | Owner: Andrea
| Zanotto
Type: Bug | Status: assigned
Component: Migrations | Version: 5.2
Severity: Normal | Resolution:
Keywords: schema alterfield | Triage Stage: Ready for
to_field attname foreignkey | checkin
Has patch: 1 | Needs documentation: 0
Needs tests: 0 | Patch needs improvement: 0
Easy pickings: 0 | UI/UX: 0
-------------------------------------+-------------------------------------
Changes (by Jacob Walls):

* stage: Accepted => Ready for checkin

--
Ticket URL: <https://code.djangoproject.com/ticket/37060#comment:6>

Django

unread,
May 7, 2026, 8:03:02 AMMay 7
to django-...@googlegroups.com
#37060: AlterField doesn't propagate type changes through transitive attname-based
to_field references
-------------------------------------+-------------------------------------
Reporter: Andrea Zanotto | Owner: Andrea
| Zanotto
Type: Bug | Status: closed
Component: Migrations | Version: 5.2
Severity: Normal | Resolution: fixed
Keywords: schema alterfield | Triage Stage: Ready for
to_field attname foreignkey | checkin
Has patch: 1 | Needs documentation: 0
Needs tests: 0 | Patch needs improvement: 0
Easy pickings: 0 | UI/UX: 0
-------------------------------------+-------------------------------------
Changes (by Jacob Walls <jacobtylerwalls@…>):

* resolution: => fixed
* status: assigned => closed

Comment:

In [changeset:"21c51c2623a966ba1ad8fd10e36bc8bbec93b70e" 21c51c2]:
{{{#!CommitTicketReference repository=""
revision="21c51c2623a966ba1ad8fd10e36bc8bbec93b70e"
Fixed #37060 -- Propagated AlterField through attname-based to_field
references.

Schema dependency discovery treated to_field values as raw field names, so
attname aliases such as "primary_id" were not matched to the underlying
relation field "primary". As a result, AlterField on a unique target field
updated direct dependencies but missed transitive attname-based
references.
Resolved the dependency matching by comparing resolved remote fields
rather than only field names, and updated SQLite's related-table rebuild
path to use the same recursive dependency discovery.
Added a regression test covering a transitive relation chain where
ForeignKey(..., to_field="primary_id") must widen along with the unique
leaf field it ultimately references.
}}}
--
Ticket URL: <https://code.djangoproject.com/ticket/37060#comment:7>

Django

unread,
May 8, 2026, 1:41:26 PMMay 8
to django-...@googlegroups.com
#37060: AlterField doesn't propagate type changes through transitive attname-based
to_field references
-------------------------------------+-------------------------------------
Reporter: Andrea Zanotto | Owner: Andrea
| Zanotto
Type: Bug | Status: closed
Component: Migrations | Version: 5.2
Severity: Normal | Resolution: fixed
Keywords: schema alterfield | Triage Stage: Ready for
to_field attname foreignkey | checkin
Has patch: 1 | Needs documentation: 0
Needs tests: 0 | Patch needs improvement: 0
Easy pickings: 0 | UI/UX: 0
-------------------------------------+-------------------------------------
Comment (by Jacob Walls <jacobtylerwalls@…>):

In [changeset:"4d455ae2d7689ce066dfffef9fc29a6f6d3ed33e" 4d455ae]:
{{{#!CommitTicketReference repository=""
revision="4d455ae2d7689ce066dfffef9fc29a6f6d3ed33e"
Refs #37060 -- Shortened app label in AlterField test for Oracle.

This avoids having to run connection.ops.truncate_name() when
deriving the table name.

Follow-up to 21c51c2623a966ba1ad8fd10e36bc8bbec93b70e.
}}}
--
Ticket URL: <https://code.djangoproject.com/ticket/37060#comment:8>
Reply all
Reply to author
Forward
0 new messages