django-bulk-hooks 0.1.252__tar.gz → 0.1.253__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.252 → django_bulk_hooks-0.1.253}/PKG-INFO +1 -1
  2. {django_bulk_hooks-0.1.252 → django_bulk_hooks-0.1.253}/django_bulk_hooks/queryset.py +58 -0
  3. {django_bulk_hooks-0.1.252 → django_bulk_hooks-0.1.253}/pyproject.toml +1 -1
  4. {django_bulk_hooks-0.1.252 → django_bulk_hooks-0.1.253}/LICENSE +0 -0
  5. {django_bulk_hooks-0.1.252 → django_bulk_hooks-0.1.253}/README.md +0 -0
  6. {django_bulk_hooks-0.1.252 → django_bulk_hooks-0.1.253}/django_bulk_hooks/__init__.py +0 -0
  7. {django_bulk_hooks-0.1.252 → django_bulk_hooks-0.1.253}/django_bulk_hooks/conditions.py +0 -0
  8. {django_bulk_hooks-0.1.252 → django_bulk_hooks-0.1.253}/django_bulk_hooks/constants.py +0 -0
  9. {django_bulk_hooks-0.1.252 → django_bulk_hooks-0.1.253}/django_bulk_hooks/context.py +0 -0
  10. {django_bulk_hooks-0.1.252 → django_bulk_hooks-0.1.253}/django_bulk_hooks/decorators.py +0 -0
  11. {django_bulk_hooks-0.1.252 → django_bulk_hooks-0.1.253}/django_bulk_hooks/engine.py +0 -0
  12. {django_bulk_hooks-0.1.252 → django_bulk_hooks-0.1.253}/django_bulk_hooks/enums.py +0 -0
  13. {django_bulk_hooks-0.1.252 → django_bulk_hooks-0.1.253}/django_bulk_hooks/handler.py +0 -0
  14. {django_bulk_hooks-0.1.252 → django_bulk_hooks-0.1.253}/django_bulk_hooks/manager.py +0 -0
  15. {django_bulk_hooks-0.1.252 → django_bulk_hooks-0.1.253}/django_bulk_hooks/models.py +0 -0
  16. {django_bulk_hooks-0.1.252 → django_bulk_hooks-0.1.253}/django_bulk_hooks/priority.py +0 -0
  17. {django_bulk_hooks-0.1.252 → django_bulk_hooks-0.1.253}/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.252
3
+ Version: 0.1.253
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
@@ -575,6 +575,55 @@ class HookQuerySetMixin:
575
575
  # If no unique fields, treat all as new
576
576
  new_records = objs
577
577
 
578
+ # Handle auto_now fields intelligently for upsert operations
579
+ # Only set auto_now fields on records that will actually be created
580
+ for obj in new_records:
581
+ for field in model_cls._meta.local_fields:
582
+ if hasattr(field, "auto_now") and field.auto_now:
583
+ field.pre_save(obj, add=True)
584
+ elif hasattr(field, "auto_now_add") and field.auto_now_add:
585
+ if getattr(obj, field.name) is None:
586
+ field.pre_save(obj, add=True)
587
+
588
+ # For existing records, preserve their original auto_now values
589
+ # We'll need to fetch them from the database to preserve the timestamps
590
+ if existing_records:
591
+ # Get the unique field values for existing records
592
+ existing_unique_values = []
593
+ for obj in existing_records:
594
+ unique_value = {}
595
+ for field_name in unique_fields:
596
+ if hasattr(obj, field_name):
597
+ unique_value[field_name] = getattr(obj, field_name)
598
+ if unique_value:
599
+ existing_unique_values.append(unique_value)
600
+
601
+ if existing_unique_values:
602
+ # Build filter to fetch existing records
603
+ existing_filters = Q()
604
+ for unique_value in existing_unique_values:
605
+ filter_kwargs = {}
606
+ for field_name, value in unique_value.items():
607
+ filter_kwargs[field_name] = value
608
+ existing_filters |= Q(**filter_kwargs)
609
+
610
+ # Fetch existing records to preserve their auto_now values
611
+ existing_db_records = model_cls.objects.filter(existing_filters)
612
+ existing_db_map = {}
613
+ for db_record in existing_db_records:
614
+ key = tuple(getattr(db_record, field) for field in unique_fields)
615
+ existing_db_map[key] = db_record
616
+
617
+ # Preserve auto_now field values for existing records
618
+ for obj in existing_records:
619
+ key = tuple(getattr(obj, field) for field in unique_fields)
620
+ if key in existing_db_map:
621
+ db_record = existing_db_map[key]
622
+ for field in model_cls._meta.local_fields:
623
+ if hasattr(field, "auto_now") and field.auto_now:
624
+ # Preserve the original updated_at timestamp
625
+ setattr(obj, field.name, getattr(db_record, field.name))
626
+
578
627
  # Run validation hooks on all records
579
628
  if not bypass_validation:
580
629
  engine.run(model_cls, VALIDATE_CREATE, objs, ctx=ctx)
@@ -586,6 +635,15 @@ class HookQuerySetMixin:
586
635
  engine.run(model_cls, BEFORE_UPDATE, existing_records, ctx=ctx)
587
636
  else:
588
637
  # For regular create operations, run create hooks before DB ops
638
+ # Handle auto_now fields normally for new records
639
+ for obj in objs:
640
+ for field in model_cls._meta.local_fields:
641
+ if hasattr(field, "auto_now") and field.auto_now:
642
+ field.pre_save(obj, add=True)
643
+ elif hasattr(field, "auto_now_add") and field.auto_now_add:
644
+ if getattr(obj, field.name) is None:
645
+ field.pre_save(obj, add=True)
646
+
589
647
  if not bypass_validation:
590
648
  engine.run(model_cls, VALIDATE_CREATE, objs, ctx=ctx)
591
649
  engine.run(model_cls, BEFORE_CREATE, objs, ctx=ctx)
@@ -1,6 +1,6 @@
1
1
  [tool.poetry]
2
2
  name = "django-bulk-hooks"
3
- version = "0.1.252"
3
+ version = "0.1.253"
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"