Add support for comparing objects that are later deleted.

Review Request #14332 — Created Feb. 6, 2025 and updated

Information

django-assert-queries
main

Reviewers

When deleting an object via any relation (including when cascading
certain types of relations), we can end up in a situation where objects
can no longer be compared.

Model object comparisons check the primary key and model type. If one of
the primary keys is null, the model falls back to checking if the two
objects are the same exact instances.

What happens with deletion is that Django will perform a query
internally during delete object collection, delete them, and erase the
primary keys. This leads to several queries that are captured that
reference an object that no longer has a primary key and won't be the
same instances the unit test would have.

The solution to this is to listen in on object deletion and record any
primary keys being deleted. Then, during Q normalization, we can wrap
every model object referenced in a query to improve its equality checks,
factoring in instances that are deleted. This allows us to compare
instances.

All unit tests pass.

Tested this with unit tests in Review Board that were breaking due to
the deletion comparison behavior in Django.

Summary ID
Add support for comparing objects that are later deleted.
When deleting an object via any relation (including when cascading certain types of relations), we can end up in a situation where objects can no longer be compared. Model object comparisons check the primary key and model type. If one of the primary keys is null, the model falls back to checking if the two objects are the same exact instances. What happens with deletion is that Django will perform a query internally during delete object collection, delete them, and erase the primary keys. This leads to several queries that are captured that reference an object that no longer has a primary key and won't be the same instances the unit test would have. The solution to this is to listen in on object deletion and record any primary keys being deleted. Then, during `Q` normalization, we can wrap every model object referenced in a query to improve its equality checks, factoring in instances that are deleted. This allows us to compare instances.
0df2ffa268ab14052910ebcd7a1b17cfa64ed47b
Description From Last Updated

'django.db.models.expressions.NegatedExpression' imported but unused Column: 1 Error code: F401

reviewbotreviewbot
Checks run (1 failed, 1 succeeded)
flake8 failed.
JSHint passed.

flake8

chipx86
chipx86
Review request changed
Change Summary:
  • Removed an unused import.
  • Updated the version to 2.0.
Commits:
Summary ID
Add support for comparing objects that are later deleted.
When deleting an object via any relation (including when cascading certain types of relations), we can end up in a situation where objects can no longer be compared. Model object comparisons check the primary key and model type. If one of the primary keys is null, the model falls back to checking if the two objects are the same exact instances. What happens with deletion is that Django will perform a query internally during delete object collection, delete them, and erase the primary keys. This leads to several queries that are captured that reference an object that no longer has a primary key and won't be the same instances the unit test would have. The solution to this is to listen in on object deletion and record any primary keys being deleted. Then, during `Q` normalization, we can wrap every model object referenced in a query to improve its equality checks, factoring in instances that are deleted. This allows us to compare instances.
4a3bb58db38e9f6026b909d1108599e211cb164a
Add support for comparing objects that are later deleted.
When deleting an object via any relation (including when cascading certain types of relations), we can end up in a situation where objects can no longer be compared. Model object comparisons check the primary key and model type. If one of the primary keys is null, the model falls back to checking if the two objects are the same exact instances. What happens with deletion is that Django will perform a query internally during delete object collection, delete them, and erase the primary keys. This leads to several queries that are captured that reference an object that no longer has a primary key and won't be the same instances the unit test would have. The solution to this is to listen in on object deletion and record any primary keys being deleted. Then, during `Q` normalization, we can wrap every model object referenced in a query to improve its equality checks, factoring in instances that are deleted. This allows us to compare instances.
0df2ffa268ab14052910ebcd7a1b17cfa64ed47b

Checks run (2 succeeded)

flake8 passed.
JSHint passed.
david
  1. Ship It!
  2.