django-bulk-hooks 0.1.253__tar.gz → 0.1.255__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.1.253 → django_bulk_hooks-0.1.255}/PKG-INFO +1 -1
- {django_bulk_hooks-0.1.253 → django_bulk_hooks-0.1.255}/django_bulk_hooks/queryset.py +49 -0
- {django_bulk_hooks-0.1.253 → django_bulk_hooks-0.1.255}/pyproject.toml +1 -1
- {django_bulk_hooks-0.1.253 → django_bulk_hooks-0.1.255}/LICENSE +0 -0
- {django_bulk_hooks-0.1.253 → django_bulk_hooks-0.1.255}/README.md +0 -0
- {django_bulk_hooks-0.1.253 → django_bulk_hooks-0.1.255}/django_bulk_hooks/__init__.py +0 -0
- {django_bulk_hooks-0.1.253 → django_bulk_hooks-0.1.255}/django_bulk_hooks/conditions.py +0 -0
- {django_bulk_hooks-0.1.253 → django_bulk_hooks-0.1.255}/django_bulk_hooks/constants.py +0 -0
- {django_bulk_hooks-0.1.253 → django_bulk_hooks-0.1.255}/django_bulk_hooks/context.py +0 -0
- {django_bulk_hooks-0.1.253 → django_bulk_hooks-0.1.255}/django_bulk_hooks/decorators.py +0 -0
- {django_bulk_hooks-0.1.253 → django_bulk_hooks-0.1.255}/django_bulk_hooks/engine.py +0 -0
- {django_bulk_hooks-0.1.253 → django_bulk_hooks-0.1.255}/django_bulk_hooks/enums.py +0 -0
- {django_bulk_hooks-0.1.253 → django_bulk_hooks-0.1.255}/django_bulk_hooks/handler.py +0 -0
- {django_bulk_hooks-0.1.253 → django_bulk_hooks-0.1.255}/django_bulk_hooks/manager.py +0 -0
- {django_bulk_hooks-0.1.253 → django_bulk_hooks-0.1.255}/django_bulk_hooks/models.py +0 -0
- {django_bulk_hooks-0.1.253 → django_bulk_hooks-0.1.255}/django_bulk_hooks/priority.py +0 -0
- {django_bulk_hooks-0.1.253 → django_bulk_hooks-0.1.255}/django_bulk_hooks/registry.py +0 -0
|
@@ -624,6 +624,41 @@ class HookQuerySetMixin:
|
|
|
624
624
|
# Preserve the original updated_at timestamp
|
|
625
625
|
setattr(obj, field.name, getattr(db_record, field.name))
|
|
626
626
|
|
|
627
|
+
# CRITICAL: Exclude auto_now fields from update_fields for existing records
|
|
628
|
+
# This prevents Django from including them in the ON CONFLICT DO UPDATE clause
|
|
629
|
+
if existing_records and update_fields:
|
|
630
|
+
logger.debug(f"Processing {len(existing_records)} existing records with update_fields: {update_fields}")
|
|
631
|
+
|
|
632
|
+
# Identify auto_now fields that should be excluded from updates
|
|
633
|
+
auto_now_fields_to_exclude = set()
|
|
634
|
+
for field in model_cls._meta.local_fields:
|
|
635
|
+
if hasattr(field, "auto_now") and field.auto_now:
|
|
636
|
+
auto_now_fields_to_exclude.add(field.name)
|
|
637
|
+
|
|
638
|
+
logger.debug(f"Found auto_now fields: {auto_now_fields_to_exclude}")
|
|
639
|
+
|
|
640
|
+
# Filter out auto_now fields from update_fields for existing records
|
|
641
|
+
if auto_now_fields_to_exclude:
|
|
642
|
+
# Create a filtered version of update_fields that excludes auto_now fields
|
|
643
|
+
filtered_update_fields = [f for f in update_fields if f not in auto_now_fields_to_exclude]
|
|
644
|
+
|
|
645
|
+
logger.debug(f"Filtered update_fields: {filtered_update_fields}")
|
|
646
|
+
logger.debug(f"Excluded auto_now fields: {auto_now_fields_to_exclude}")
|
|
647
|
+
|
|
648
|
+
# Store the original update_fields to restore later
|
|
649
|
+
ctx.original_update_fields = update_fields
|
|
650
|
+
ctx.auto_now_fields_excluded = auto_now_fields_to_exclude
|
|
651
|
+
|
|
652
|
+
# Use the filtered update_fields for the database operation
|
|
653
|
+
# This prevents Django from overwriting the timestamps during upsert
|
|
654
|
+
update_fields = filtered_update_fields
|
|
655
|
+
|
|
656
|
+
logger.debug(f"Final update_fields for DB operation: {update_fields}")
|
|
657
|
+
else:
|
|
658
|
+
logger.debug("No auto_now fields found to exclude")
|
|
659
|
+
else:
|
|
660
|
+
logger.debug(f"No existing records or update_fields to process. existing_records: {len(existing_records) if existing_records else 0}, update_fields: {update_fields}")
|
|
661
|
+
|
|
627
662
|
# Run validation hooks on all records
|
|
628
663
|
if not bypass_validation:
|
|
629
664
|
engine.run(model_cls, VALIDATE_CREATE, objs, ctx=ctx)
|
|
@@ -672,6 +707,10 @@ class HookQuerySetMixin:
|
|
|
672
707
|
# but we need to call it on the base manager to avoid recursion
|
|
673
708
|
# Filter out custom parameters that Django's bulk_create doesn't accept
|
|
674
709
|
|
|
710
|
+
logger.debug(f"Calling Django bulk_create with update_fields: {update_fields}")
|
|
711
|
+
logger.debug(f"Calling Django bulk_create with update_conflicts: {update_conflicts}")
|
|
712
|
+
logger.debug(f"Calling Django bulk_create with unique_fields: {unique_fields}")
|
|
713
|
+
|
|
675
714
|
result = super().bulk_create(
|
|
676
715
|
objs,
|
|
677
716
|
batch_size=batch_size,
|
|
@@ -680,10 +719,20 @@ class HookQuerySetMixin:
|
|
|
680
719
|
update_fields=update_fields,
|
|
681
720
|
unique_fields=unique_fields,
|
|
682
721
|
)
|
|
722
|
+
|
|
723
|
+
logger.debug(f"Django bulk_create completed with result: {result}")
|
|
683
724
|
|
|
684
725
|
# Fire AFTER hooks
|
|
685
726
|
if not bypass_hooks:
|
|
686
727
|
if update_conflicts and unique_fields:
|
|
728
|
+
# Restore original update_fields if we modified them
|
|
729
|
+
if hasattr(ctx, 'original_update_fields'):
|
|
730
|
+
logger.debug(f"Restoring original update_fields: {ctx.original_update_fields}")
|
|
731
|
+
update_fields = ctx.original_update_fields
|
|
732
|
+
delattr(ctx, 'original_update_fields')
|
|
733
|
+
delattr(ctx, 'auto_now_fields_excluded')
|
|
734
|
+
logger.debug(f"Restored update_fields: {update_fields}")
|
|
735
|
+
|
|
687
736
|
# For upsert operations, we need to determine which records were actually created vs updated
|
|
688
737
|
# Use the same logic as before to separate records
|
|
689
738
|
existing_records = []
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
[tool.poetry]
|
|
2
2
|
name = "django-bulk-hooks"
|
|
3
|
-
version = "0.1.
|
|
3
|
+
version = "0.1.255"
|
|
4
4
|
description = "Hook-style hooks for Django bulk operations like bulk_create and bulk_update."
|
|
5
5
|
authors = ["Konrad Beck <konrad.beck@merchantcapital.co.za>"]
|
|
6
6
|
readme = "README.md"
|
|
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
|