#36704: Proxy model with a CompositePrimaryKey fails system check with false
positive: (models.E042) '<field>' cannot be included in the composite
primary key
-------------------------------------+-------------------------------------
Reporter: Hal Blackburn | Type: Bug
Status: new | Component: Core
| (System checks)
Version: 5.2 | Severity: Normal
Keywords: | Triage Stage:
| Unreviewed
Has patch: 1 | Needs documentation: 0
Needs tests: 0 | Patch needs improvement: 0
Easy pickings: 0 | UI/UX: 0
-------------------------------------+-------------------------------------
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
[
https://github.com/django/django/blob/05ba1a9228128614fb3c475f1c4bdf0160f44dba/django/db/models/base.py#L1825-L1826
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.
--
Ticket URL: <
https://code.djangoproject.com/ticket/36704>
Django <
https://code.djangoproject.com/>
The Web framework for perfectionists with deadlines.