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.

Files changed (17) hide show
  1. {django_bulk_hooks-0.1.253 → django_bulk_hooks-0.1.255}/PKG-INFO +1 -1
  2. {django_bulk_hooks-0.1.253 → django_bulk_hooks-0.1.255}/django_bulk_hooks/queryset.py +49 -0
  3. {django_bulk_hooks-0.1.253 → django_bulk_hooks-0.1.255}/pyproject.toml +1 -1
  4. {django_bulk_hooks-0.1.253 → django_bulk_hooks-0.1.255}/LICENSE +0 -0
  5. {django_bulk_hooks-0.1.253 → django_bulk_hooks-0.1.255}/README.md +0 -0
  6. {django_bulk_hooks-0.1.253 → django_bulk_hooks-0.1.255}/django_bulk_hooks/__init__.py +0 -0
  7. {django_bulk_hooks-0.1.253 → django_bulk_hooks-0.1.255}/django_bulk_hooks/conditions.py +0 -0
  8. {django_bulk_hooks-0.1.253 → django_bulk_hooks-0.1.255}/django_bulk_hooks/constants.py +0 -0
  9. {django_bulk_hooks-0.1.253 → django_bulk_hooks-0.1.255}/django_bulk_hooks/context.py +0 -0
  10. {django_bulk_hooks-0.1.253 → django_bulk_hooks-0.1.255}/django_bulk_hooks/decorators.py +0 -0
  11. {django_bulk_hooks-0.1.253 → django_bulk_hooks-0.1.255}/django_bulk_hooks/engine.py +0 -0
  12. {django_bulk_hooks-0.1.253 → django_bulk_hooks-0.1.255}/django_bulk_hooks/enums.py +0 -0
  13. {django_bulk_hooks-0.1.253 → django_bulk_hooks-0.1.255}/django_bulk_hooks/handler.py +0 -0
  14. {django_bulk_hooks-0.1.253 → django_bulk_hooks-0.1.255}/django_bulk_hooks/manager.py +0 -0
  15. {django_bulk_hooks-0.1.253 → django_bulk_hooks-0.1.255}/django_bulk_hooks/models.py +0 -0
  16. {django_bulk_hooks-0.1.253 → django_bulk_hooks-0.1.255}/django_bulk_hooks/priority.py +0 -0
  17. {django_bulk_hooks-0.1.253 → django_bulk_hooks-0.1.255}/django_bulk_hooks/registry.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.3
2
2
  Name: django-bulk-hooks
3
- Version: 0.1.253
3
+ Version: 0.1.255
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
@@ -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.253"
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"