django-bulk-hooks 0.2.48__py3-none-any.whl → 0.2.49__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.

Potentially problematic release.


This version of django-bulk-hooks might be problematic. Click here for more details.

@@ -78,8 +78,7 @@ class MTIHandler:
78
78
  chain.append(current_model)
79
79
 
80
80
  # Get concrete parent models (not abstract, not proxy)
81
- parents = [parent for parent in current_model._meta.parents.keys()
82
- if not parent._meta.proxy and not parent._meta.abstract]
81
+ parents = [parent for parent in current_model._meta.parents.keys() if not parent._meta.proxy and not parent._meta.abstract]
83
82
 
84
83
  current_model = parents[0] if parents else None
85
84
 
@@ -113,31 +112,33 @@ class MTIHandler:
113
112
 
114
113
  def find_model_with_unique_fields(self, unique_fields):
115
114
  """
116
- Find which model in the inheritance chain contains the unique fields.
117
-
118
- This is critical for MTI upserts: we need to query the model that has
119
- the unique constraint, not necessarily the child model.
120
-
115
+ Find which model in the inheritance chain to query for existing records.
116
+
117
+ For MTI upsert operations, we need to determine if the parent record exists
118
+ to properly fire AFTER_CREATE vs AFTER_UPDATE hooks. This is critical because:
119
+ - If parent exists but child doesn't: creating child for existing parent → AFTER_UPDATE
120
+ - If neither exists: creating both parent and child → AFTER_CREATE
121
+
122
+ Therefore, we return the root parent model to check if the parent record exists,
123
+ regardless of where the unique fields are defined.
124
+
121
125
  Args:
122
126
  unique_fields: List of field names forming the unique constraint
123
-
127
+
124
128
  Returns:
125
- Model class that contains all the unique fields (closest to root)
129
+ Model class to query for existing records (root parent for MTI)
126
130
  """
127
131
  if not unique_fields:
128
132
  return self.model_cls
129
-
133
+
130
134
  inheritance_chain = self.get_inheritance_chain()
131
-
132
- # Start from root and find the first model that has all unique fields
133
- for model_cls in inheritance_chain:
134
- model_field_names = {f.name for f in model_cls._meta.local_fields}
135
-
136
- # Check if this model has all the unique fields
137
- if all(field in model_field_names for field in unique_fields):
138
- return model_cls
139
-
140
- # Fallback to child model (shouldn't happen if unique_fields are valid)
135
+
136
+ # For MTI models with multiple levels, return the root parent model
137
+ # This ensures we check if the parent exists, which determines create vs update hooks
138
+ if len(inheritance_chain) > 1:
139
+ return inheritance_chain[0] # Root parent model
140
+
141
+ # For non-MTI models (shouldn't happen, but safe fallback)
141
142
  return self.model_cls
142
143
 
143
144
  # ==================== MTI BULK CREATE PLANNING ====================
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.3
2
2
  Name: django-bulk-hooks
3
- Version: 0.2.48
3
+ Version: 0.2.49
4
4
  Summary: Hook-style hooks for Django bulk operations like bulk_create and bulk_update.
5
5
  License: MIT
6
6
  Keywords: django,bulk,hooks
@@ -15,12 +15,12 @@ django_bulk_hooks/operations/__init__.py,sha256=BtJYjmRhe_sScivLsniDaZmBkm0ZLvcm
15
15
  django_bulk_hooks/operations/analyzer.py,sha256=wAG8sAG9NwfwNqG9z81VfGR7AANDzRmMGE_o82MWji4,10689
16
16
  django_bulk_hooks/operations/bulk_executor.py,sha256=RbvmYaZw94H31D3HMlK_hwWaHSy8Y3l8juxIzegtS7k,23527
17
17
  django_bulk_hooks/operations/coordinator.py,sha256=iGavJLqe3eYRqFay8cMn6muwyRYzQo-HFGphsS5hL6g,30799
18
- django_bulk_hooks/operations/mti_handler.py,sha256=GIpTzzoo_hx1iI5osx2COk3cVQgqTsD-o41d9S7aiqo,20748
18
+ django_bulk_hooks/operations/mti_handler.py,sha256=uDrfE29e80v4YjPF4fPw2x0bntRnFGyfEh-grMQUGu0,20907
19
19
  django_bulk_hooks/operations/mti_plans.py,sha256=7STQ2oA2ZT8cEG3-t-6xciRAdf7OeSf0gRLXR_BRG-Q,3363
20
20
  django_bulk_hooks/operations/record_classifier.py,sha256=vNi0WSNiPAVb8pTZZJ26b81oX59snk7LIxWMzyenDCk,6694
21
21
  django_bulk_hooks/queryset.py,sha256=aQitlbexcVnmeAdc0jtO3hci39p4QEu4srQPEzozy5s,5546
22
22
  django_bulk_hooks/registry.py,sha256=uum5jhGI3TPaoiXuA1MdBdu4gbE3rQGGwQ5YDjiMcjk,7949
23
- django_bulk_hooks-0.2.48.dist-info/LICENSE,sha256=dguKIcbDGeZD-vXWdLyErPUALYOvtX_fO4Zjhq481uk,1088
24
- django_bulk_hooks-0.2.48.dist-info/METADATA,sha256=R6l5_Y49oVdJK6YSLF6zRuRUVIuVSkUILudpFQKCumI,9265
25
- django_bulk_hooks-0.2.48.dist-info/WHEEL,sha256=b4K_helf-jlQoXBBETfwnf4B04YC67LOev0jo4fX5m8,88
26
- django_bulk_hooks-0.2.48.dist-info/RECORD,,
23
+ django_bulk_hooks-0.2.49.dist-info/LICENSE,sha256=dguKIcbDGeZD-vXWdLyErPUALYOvtX_fO4Zjhq481uk,1088
24
+ django_bulk_hooks-0.2.49.dist-info/METADATA,sha256=ROH2Js_T0cGMRLaxUQnx9ZOQr9Rteii1n5MF0EJHqh8,9265
25
+ django_bulk_hooks-0.2.49.dist-info/WHEEL,sha256=b4K_helf-jlQoXBBETfwnf4B04YC67LOev0jo4fX5m8,88
26
+ django_bulk_hooks-0.2.49.dist-info/RECORD,,