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.
- {django_bulk_hooks-0.1.252 → django_bulk_hooks-0.1.253}/PKG-INFO +1 -1
- {django_bulk_hooks-0.1.252 → django_bulk_hooks-0.1.253}/django_bulk_hooks/queryset.py +58 -0
- {django_bulk_hooks-0.1.252 → django_bulk_hooks-0.1.253}/pyproject.toml +1 -1
- {django_bulk_hooks-0.1.252 → django_bulk_hooks-0.1.253}/LICENSE +0 -0
- {django_bulk_hooks-0.1.252 → django_bulk_hooks-0.1.253}/README.md +0 -0
- {django_bulk_hooks-0.1.252 → django_bulk_hooks-0.1.253}/django_bulk_hooks/__init__.py +0 -0
- {django_bulk_hooks-0.1.252 → django_bulk_hooks-0.1.253}/django_bulk_hooks/conditions.py +0 -0
- {django_bulk_hooks-0.1.252 → django_bulk_hooks-0.1.253}/django_bulk_hooks/constants.py +0 -0
- {django_bulk_hooks-0.1.252 → django_bulk_hooks-0.1.253}/django_bulk_hooks/context.py +0 -0
- {django_bulk_hooks-0.1.252 → django_bulk_hooks-0.1.253}/django_bulk_hooks/decorators.py +0 -0
- {django_bulk_hooks-0.1.252 → django_bulk_hooks-0.1.253}/django_bulk_hooks/engine.py +0 -0
- {django_bulk_hooks-0.1.252 → django_bulk_hooks-0.1.253}/django_bulk_hooks/enums.py +0 -0
- {django_bulk_hooks-0.1.252 → django_bulk_hooks-0.1.253}/django_bulk_hooks/handler.py +0 -0
- {django_bulk_hooks-0.1.252 → django_bulk_hooks-0.1.253}/django_bulk_hooks/manager.py +0 -0
- {django_bulk_hooks-0.1.252 → django_bulk_hooks-0.1.253}/django_bulk_hooks/models.py +0 -0
- {django_bulk_hooks-0.1.252 → django_bulk_hooks-0.1.253}/django_bulk_hooks/priority.py +0 -0
- {django_bulk_hooks-0.1.252 → django_bulk_hooks-0.1.253}/django_bulk_hooks/registry.py +0 -0
|
@@ -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.
|
|
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"
|
|
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
|