@@ -1428,18 +1428,55 @@ def __init__(
14281428
14291429 def _make_query (self ) -> None :
14301430 self .query = copy (self .model ._meta .basequery )
1431- if self .capabilities .support_update_limit_order_by and self ._limit :
1432- self .query ._limit = self .query ._wrapper_cls (self ._limit )
1431+ self .resolve_filters ()
1432+
1433+ # If joins are detected, rewrite into an IN subquery to avoid JOINs in DELETE
1434+ if self ._joined_tables :
1435+ pk_column = self .model ._meta .db_pk_column
1436+
1437+ # Create a pristine, completely separate SELECT query builder
1438+ subquery = self ._db .query_class .from_ (self .model ._meta .basetable ).select (
1439+ self .model ._meta .basetable [pk_column ]
1440+ )
1441+
1442+ # Transfer the resolved wheres and havings criteria from our filter resolution
1443+ subquery ._wheres = self .query ._wheres
1444+ subquery ._havings = self .query ._havings
1445+
1446+ # Apply joins directly to the subquery builder
1447+ subquery ._joins = self .query ._joins
1448+
1449+ # Re-apply limits and sorting to the subquery if needed
1450+ if self ._limit :
1451+ subquery ._limit = subquery ._wrapper_cls (self ._limit )
1452+
14331453 self .resolve_ordering (
14341454 model = self .model ,
14351455 table = self .model ._meta .basetable ,
14361456 orderings = self ._orderings ,
14371457 annotations = self ._annotations ,
14381458 )
1439- self .resolve_filters ()
1459+ subquery ._orderbys = self .query ._orderbys
1460+
1461+ # Reconstruct clean pristine delete statement pointing to our subquery
1462+ self .query = copy (self .model ._meta .basequery )
1463+ self .query = self .query .where (
1464+ self .model ._meta .basetable [pk_column ].isin (subquery )
1465+ )
1466+ else :
1467+ # Traditional optimization path if no backward relations/joins exist
1468+ if self .capabilities .support_update_limit_order_by and self ._limit :
1469+ self .query ._limit = self .query ._wrapper_cls (self ._limit )
1470+ self .resolve_ordering (
1471+ model = self .model ,
1472+ table = self .model ._meta .basetable ,
1473+ orderings = self ._orderings ,
1474+ annotations = self ._annotations ,
1475+ )
1476+
14401477 self .query ._delete_from = True
14411478 return
1442-
1479+
14431480 def __await__ (self ) -> Generator [Any , None , int ]:
14441481 self ._choose_db_if_not_chosen (True )
14451482 self ._make_query ()
0 commit comments