django-bulk-hooks 0.2.8__tar.gz → 0.2.9__tar.gz
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.
- {django_bulk_hooks-0.2.8 → django_bulk_hooks-0.2.9}/PKG-INFO +1 -1
- {django_bulk_hooks-0.2.8 → django_bulk_hooks-0.2.9}/django_bulk_hooks/operations/analyzer.py +63 -1
- {django_bulk_hooks-0.2.8 → django_bulk_hooks-0.2.9}/pyproject.toml +1 -1
- {django_bulk_hooks-0.2.8 → django_bulk_hooks-0.2.9}/LICENSE +0 -0
- {django_bulk_hooks-0.2.8 → django_bulk_hooks-0.2.9}/README.md +0 -0
- {django_bulk_hooks-0.2.8 → django_bulk_hooks-0.2.9}/django_bulk_hooks/__init__.py +0 -0
- {django_bulk_hooks-0.2.8 → django_bulk_hooks-0.2.9}/django_bulk_hooks/changeset.py +0 -0
- {django_bulk_hooks-0.2.8 → django_bulk_hooks-0.2.9}/django_bulk_hooks/conditions.py +0 -0
- {django_bulk_hooks-0.2.8 → django_bulk_hooks-0.2.9}/django_bulk_hooks/constants.py +0 -0
- {django_bulk_hooks-0.2.8 → django_bulk_hooks-0.2.9}/django_bulk_hooks/context.py +0 -0
- {django_bulk_hooks-0.2.8 → django_bulk_hooks-0.2.9}/django_bulk_hooks/debug_utils.py +0 -0
- {django_bulk_hooks-0.2.8 → django_bulk_hooks-0.2.9}/django_bulk_hooks/decorators.py +0 -0
- {django_bulk_hooks-0.2.8 → django_bulk_hooks-0.2.9}/django_bulk_hooks/dispatcher.py +0 -0
- {django_bulk_hooks-0.2.8 → django_bulk_hooks-0.2.9}/django_bulk_hooks/enums.py +0 -0
- {django_bulk_hooks-0.2.8 → django_bulk_hooks-0.2.9}/django_bulk_hooks/factory.py +0 -0
- {django_bulk_hooks-0.2.8 → django_bulk_hooks-0.2.9}/django_bulk_hooks/handler.py +0 -0
- {django_bulk_hooks-0.2.8 → django_bulk_hooks-0.2.9}/django_bulk_hooks/helpers.py +0 -0
- {django_bulk_hooks-0.2.8 → django_bulk_hooks-0.2.9}/django_bulk_hooks/manager.py +0 -0
- {django_bulk_hooks-0.2.8 → django_bulk_hooks-0.2.9}/django_bulk_hooks/models.py +0 -0
- {django_bulk_hooks-0.2.8 → django_bulk_hooks-0.2.9}/django_bulk_hooks/operations/__init__.py +0 -0
- {django_bulk_hooks-0.2.8 → django_bulk_hooks-0.2.9}/django_bulk_hooks/operations/bulk_executor.py +0 -0
- {django_bulk_hooks-0.2.8 → django_bulk_hooks-0.2.9}/django_bulk_hooks/operations/coordinator.py +0 -0
- {django_bulk_hooks-0.2.8 → django_bulk_hooks-0.2.9}/django_bulk_hooks/operations/mti_handler.py +0 -0
- {django_bulk_hooks-0.2.8 → django_bulk_hooks-0.2.9}/django_bulk_hooks/operations/mti_plans.py +0 -0
- {django_bulk_hooks-0.2.8 → django_bulk_hooks-0.2.9}/django_bulk_hooks/queryset.py +0 -0
- {django_bulk_hooks-0.2.8 → django_bulk_hooks-0.2.9}/django_bulk_hooks/registry.py +0 -0
{django_bulk_hooks-0.2.8 → django_bulk_hooks-0.2.9}/django_bulk_hooks/operations/analyzer.py
RENAMED
|
@@ -257,6 +257,10 @@ class ModelAnalyzer:
|
|
|
257
257
|
F() expressions, Subquery, Case, etc.) into concrete values and applies
|
|
258
258
|
them to the instances.
|
|
259
259
|
|
|
260
|
+
CRITICAL: When setting FK fields by their attname (e.g., business_id),
|
|
261
|
+
we must manually clear the relationship cache (e.g., business) to match
|
|
262
|
+
Django's ForeignKey descriptor behavior.
|
|
263
|
+
|
|
260
264
|
Args:
|
|
261
265
|
instances: List of model instances to update
|
|
262
266
|
update_kwargs: Dict of {field_name: value_or_expression}
|
|
@@ -270,8 +274,66 @@ class ModelAnalyzer:
|
|
|
270
274
|
fields_updated = list(update_kwargs.keys())
|
|
271
275
|
|
|
272
276
|
for field_name, value in update_kwargs.items():
|
|
277
|
+
# Determine if this is a FK field being set by its attname
|
|
278
|
+
field_info = self._get_fk_field_info(field_name)
|
|
279
|
+
|
|
273
280
|
for instance in instances:
|
|
274
281
|
resolved_value = self.resolve_expression(field_name, value, instance)
|
|
275
282
|
setattr(instance, field_name, resolved_value)
|
|
283
|
+
|
|
284
|
+
# Clear relationship cache when FK field is set directly
|
|
285
|
+
# This replicates Django's ForeignKey descriptor behavior
|
|
286
|
+
if field_info and field_info['is_fk_attname']:
|
|
287
|
+
self._clear_fk_cache(instance, field_info['accessor_name'])
|
|
288
|
+
|
|
289
|
+
return fields_updated
|
|
290
|
+
|
|
291
|
+
def _get_fk_field_info(self, field_name):
|
|
292
|
+
"""
|
|
293
|
+
Get information about a FK field if field_name is a FK attname.
|
|
294
|
+
|
|
295
|
+
Args:
|
|
296
|
+
field_name: Field name to check
|
|
297
|
+
|
|
298
|
+
Returns:
|
|
299
|
+
Dict with FK info or None if not a FK field
|
|
300
|
+
"""
|
|
301
|
+
try:
|
|
302
|
+
# Check all fields to find if this is a FK attname
|
|
303
|
+
for field in self.model_cls._meta.get_fields():
|
|
304
|
+
if (field.is_relation and
|
|
305
|
+
not field.many_to_many and
|
|
306
|
+
not field.one_to_many and
|
|
307
|
+
hasattr(field, 'attname') and
|
|
308
|
+
field.attname == field_name):
|
|
309
|
+
# This is a FK field being set by its attname (e.g., business_id)
|
|
310
|
+
return {
|
|
311
|
+
'is_fk_attname': True,
|
|
312
|
+
'accessor_name': field.name, # e.g., 'business'
|
|
313
|
+
'field': field
|
|
314
|
+
}
|
|
315
|
+
except Exception as e:
|
|
316
|
+
logger.debug(f"Error checking FK field info for {field_name}: {e}")
|
|
317
|
+
|
|
318
|
+
return None
|
|
319
|
+
|
|
320
|
+
def _clear_fk_cache(self, instance, accessor_name):
|
|
321
|
+
"""
|
|
322
|
+
Clear cached relationship when FK field is set directly.
|
|
276
323
|
|
|
277
|
-
|
|
324
|
+
This replicates what Django's ForeignKey descriptor __set__ does:
|
|
325
|
+
when you set a FK field, Django clears the cached related object.
|
|
326
|
+
|
|
327
|
+
Args:
|
|
328
|
+
instance: Model instance
|
|
329
|
+
accessor_name: Name of the relationship accessor (e.g., 'business')
|
|
330
|
+
"""
|
|
331
|
+
try:
|
|
332
|
+
if hasattr(instance, '_state') and hasattr(instance._state, 'fields_cache'):
|
|
333
|
+
instance._state.fields_cache.pop(accessor_name, None)
|
|
334
|
+
logger.debug(
|
|
335
|
+
f"Cleared FK cache for '{accessor_name}' on {self.model_cls.__name__}"
|
|
336
|
+
)
|
|
337
|
+
except Exception as e:
|
|
338
|
+
# Don't fail the operation, just log
|
|
339
|
+
logger.debug(f"Could not clear FK cache for {accessor_name}: {e}")
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{django_bulk_hooks-0.2.8 → django_bulk_hooks-0.2.9}/django_bulk_hooks/operations/__init__.py
RENAMED
|
File without changes
|
{django_bulk_hooks-0.2.8 → django_bulk_hooks-0.2.9}/django_bulk_hooks/operations/bulk_executor.py
RENAMED
|
File without changes
|
{django_bulk_hooks-0.2.8 → django_bulk_hooks-0.2.9}/django_bulk_hooks/operations/coordinator.py
RENAMED
|
File without changes
|
{django_bulk_hooks-0.2.8 → django_bulk_hooks-0.2.9}/django_bulk_hooks/operations/mti_handler.py
RENAMED
|
File without changes
|
{django_bulk_hooks-0.2.8 → django_bulk_hooks-0.2.9}/django_bulk_hooks/operations/mti_plans.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|