Opened 7 hours ago

Last modified 105 minutes ago

#36704 assigned Bug

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: Accepted
Has patch: no 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 (4)

comment:1 by Clifford Gama, 6 hours 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, 4 hours 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, 4 hours ago

Owner: set to Hal Blackburn
Status: newassigned

comment:4 by Jacob Walls, 105 minutes ago

Keywords: compositeprimarykey added
Severity: NormalRelease blocker
Note: See TracTickets for help on using tickets.
Back to Top