Opened 3 weeks ago

Closed 3 weeks ago

Last modified 3 weeks ago

#36704 closed Bug (fixed)

Proxy model with a CompositePrimaryKey fails system check with false positive: (models.E042) '<field>' cannot be included in the composite primary key

Reported by: Hal Blackburn Owned by: Hal Blackburn
Component: Core (System checks) Version: 5.2
Severity: Release blocker Keywords: compositeprimarykey
Cc: Hal Blackburn Triage Stage: Ready for checkin
Has patch: yes Needs documentation: no
Needs tests: no Patch needs improvement: no
Easy pickings: no UI/UX: no

Description

A proxy subclass model of a parent model that uses CompositePrimaryKey causes manage.py check to fail:

$ python manage.py check
SystemCheckError: System check identified some issues:

ERRORS:
example.ProxyOrderLineItem: (models.E042) 'order_id' cannot be included in the composite primary key.
        HINT: 'order_id' field is not a local field.
example.ProxyOrderLineItem: (models.E042) 'product_id' cannot be included in the composite primary key.
        HINT: 'product_id' field is not a local field.

System check identified 2 issues (0 silenced).

This models.py module will reproduce the issue:

# Example from https://docs.djangoproject.com/en/5.2/topics/composite-primary-key/
from django.db import models


class Product(models.Model):
    name = models.CharField(max_length=100)


class Order(models.Model):
    reference = models.CharField(max_length=20, primary_key=True)


class OrderLineItem(models.Model):
    pk = models.CompositePrimaryKey("product_id", "order_id")
    product = models.ForeignKey(Product, on_delete=models.CASCADE)
    order = models.ForeignKey(Order, on_delete=models.CASCADE)
    quantity = models.IntegerField()


# This proxy model triggers the check error
class ProxyOrderLineItem(OrderLineItem):
    class Meta:
        proxy = True

The issue is caused by these two lines of the checks for classes with CompositePrimaryKey:

            elif field not in meta.local_fields:
                hint = f"{field_name!r} field is not a local field."

The meta.local_fields is empty for proxy subclasses, but the check passes for the parent class because the meta.local_fields contains the fields in the parent.

I believe this is a false-positive, as the proxy model seems to work as expected if the failed checks are suppressed.

Change History (9)

comment:1 by Clifford Gama, 3 weeks ago

Has patch: unset
Triage Stage: UnreviewedAccepted

Thanks for the report!

Would you like to prepare a patch?

Since _check_composite_pk() has no proxy-model specific checks, we may also choose to skip the checks for proxy models. This would fix this issue and prevent duplicate errors reports when there are errors.

comment:2 by Hal Blackburn, 3 weeks ago

You're welcome! Sure, I'd be happy to make a patch.

Good idea to skip these checks for proxy models. Shall we return early from _check_composite_pk() at this point that if not isinstance(pk, CompositePrimaryKey): also returns early?

comment:3 by Hal Blackburn, 3 weeks ago

Owner: set to Hal Blackburn
Status: newassigned

comment:4 by Jacob Walls, 3 weeks ago

Keywords: compositeprimarykey added
Severity: NormalRelease blocker

comment:5 by Hal Blackburn, 3 weeks ago

Has patch: set

comment:6 by Clifford Gama, 3 weeks ago

Triage Stage: AcceptedReady for checkin

comment:7 by Jacob Walls <jacobtylerwalls@…>, 3 weeks ago

Resolution: fixed
Status: assignedclosed

In 74564946:

Fixed #36704 -- Fixed system check error for proxy model with a composite pk.

Proxy models subclassing a model with a CompositePrimaryKey were
incorrectly reporting check errors because the check that requires only
local fields to be used in a composite pk was evaluated against the proxy
subclass, which has no fields.

To fix this, composite pk field checks are not evaluated against
proxy subclasses, as none of the checks are applicable to proxy
subclasses. This also has the benefit of not double-reporting real check
errors from an invalid superclass pk.

Thanks Clifford Gama for the review.

comment:8 by Jacob Walls <jacobtylerwalls@…>, 3 weeks ago

In 12042b8:

[6.0.x] Fixed #36704 -- Fixed system check error for proxy model with a composite pk.

Proxy models subclassing a model with a CompositePrimaryKey were
incorrectly reporting check errors because the check that requires only
local fields to be used in a composite pk was evaluated against the proxy
subclass, which has no fields.

To fix this, composite pk field checks are not evaluated against
proxy subclasses, as none of the checks are applicable to proxy
subclasses. This also has the benefit of not double-reporting real check
errors from an invalid superclass pk.

Thanks Clifford Gama for the review.

Backport of 74564946c3b42a2ef7d087047e49873847a7e1d9 from main.

comment:9 by Jacob Walls <jacobtylerwalls@…>, 3 weeks ago

In cbdf128:

[5.2.x] Fixed #36704 -- Fixed system check error for proxy model with a composite pk.

Proxy models subclassing a model with a CompositePrimaryKey were
incorrectly reporting check errors because the check that requires only
local fields to be used in a composite pk was evaluated against the proxy
subclass, which has no fields.

To fix this, composite pk field checks are not evaluated against
proxy subclasses, as none of the checks are applicable to proxy
subclasses. This also has the benefit of not double-reporting real check
errors from an invalid superclass pk.

Thanks Clifford Gama for the review.

Backport of 74564946c3b42a2ef7d087047e49873847a7e1d9 from main.

Note: See TracTickets for help on using tickets.
Back to Top