#34743 closed Bug (fixed)

full_clean() raises AttributeError on constraints with related IDs.

Reported by: NWAWEL A IROUME Owned by: Francesco Panico
Component: Database layer (models, ORM) Version: 4.2
Severity: Normal Keywords: constraints, models, integrity
Cc: nwawelairoume14@…, n.iroume@…, wdmofor@…, Gagaro 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

from django.db import models
from django.db.models.constraints import CheckConstraint
from django.db.models import F, Q

# model with self FK
class Structure(models.Model):
    upper_structure = models.ForeignKey(
            "self",
            on_delete=models.SET_NULL,
            null=True,
            blank=True,
            related_name="structures",
        )

    class Meta:
            constraints = [
                # un poste ne peut pas etre lui-meme sont poste superieur
                CheckConstraint(
                    check=~Q(pk=F("upper_structure__pk")),
                    name="%(app_label)s_%(class)s_upper_structure_not_equals_self",
                )
            ]

# check the issue here
s = Structure()
s.full_clean()

Expected behavior calling full_clean() shoul not trigger the error

#Here is the stack trace

File "/home/plexuserp/venv/lib/python3.11/site-packages/django/db/models/base.py", line 1491, in full_clean
self.validate_constraints(exclude=exclude)
File "/home/plexuserp/venv/lib/python3.11/site-packages/django/db/models/base.py", line 1442, in validate_constraints
constraint.validate(model_class, self, exclude=exclude, using=using)
File "/home/plexuserp/venv/lib/python3.11/site-packages/django/db/models/constraints.py", line 92, in validate
if not Q(self.check).check(against, using=using):
        ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/home/plexuserp/venv/lib/python3.11/site-packages/django/db/models/query_utils.py", line 134, in check
query.add_q(self)
File "/home/plexuserp/venv/lib/python3.11/site-packages/django/db/models/sql/query.py", line 1532, in add_q
clause, _ = self._add_q(q_object, self.used_aliases)
            ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/home/plexuserp/venv/lib/python3.11/site-packages/django/db/models/sql/query.py", line 1562, in _add_q
child_clause, needed_inner = self.build_filter(
                                ^^^^^^^^^^^^^^^^^^
File "/home/plexuserp/venv/lib/python3.11/site-packages/django/db/models/sql/query.py", line 1388, in build_filter
return self._add_q(
        ^^^^^^^^^^^^
File "/home/plexuserp/venv/lib/python3.11/site-packages/django/db/models/sql/query.py", line 1562, in _add_q
child_clause, needed_inner = self.build_filter(
                                ^^^^^^^^^^^^^^^^^^
File "/home/plexuserp/venv/lib/python3.11/site-packages/django/db/models/sql/query.py", line 1407, in build_filter
lookups, parts, reffed_expression = self.solve_lookup_type(arg)
                                    ^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/home/plexuserp/venv/lib/python3.11/site-packages/django/db/models/sql/query.py", line 1217, in solve_lookup_type
_, field, _, lookup_parts = self.names_to_path(lookup_splitted, self.get_meta())
                            ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/home/plexuserp/venv/lib/python3.11/site-packages/django/db/models/sql/query.py", line 1656, in names_to_path
name = opts.pk.name
           ^^^^^^^
AttributeError: 'NoneType' object has no attribute 'pk'

Change History (7)

comment:1 by Mariusz Felisiak, 17 months ago

Summary: AttributeError: 'NoneType' object has no attribute 'pk' when calling full_clean() on a model instance with a self referencing constraintfull_clean() raises AttributeError on constraints with related IDs.
Triage Stage: UnreviewedAccepted

Constraints that refers to the joined field are not allowed:

$ python manage migrate
SystemCheckError: System check identified some issues:

ERRORS:
test_one.Structure: (models.E041) 'constraints' refers to the joined field 'upper_structure__pk'.

However, it raises the same error for check=~Q(pk=F("upper_structure_id")) which is allowed.

comment:2 by Mariusz Felisiak, 17 months ago

Cc: Gagaro added

comment:3 by Francesco Panico, 17 months ago

Owner: changed from nobody to Francesco Panico
Status: newassigned

comment:4 by Francesco Panico, 17 months ago

Has patch: set

comment:5 by Mariusz Felisiak, 17 months ago

Patch needs improvement: set

comment:6 by Mariusz Felisiak, 17 months ago

Patch needs improvement: unset
Triage Stage: AcceptedReady for checkin

comment:7 by Mariusz Felisiak <felisiak.mariusz@…>, 17 months ago

Resolution: fixed
Status: assignedclosed

In 1506f498:

Fixed #34743 -- Fixed Meta.constraints validation crash when using pk.

Thanks Nwawel A Iroume for the report.

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