django-bulk-hooks 0.1.279__tar.gz → 0.1.281__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.279 → django_bulk_hooks-0.1.281}/PKG-INFO +1 -1
- {django_bulk_hooks-0.1.279 → django_bulk_hooks-0.1.281}/django_bulk_hooks/queryset.py +83 -10
- {django_bulk_hooks-0.1.279 → django_bulk_hooks-0.1.281}/pyproject.toml +1 -1
- {django_bulk_hooks-0.1.279 → django_bulk_hooks-0.1.281}/LICENSE +0 -0
- {django_bulk_hooks-0.1.279 → django_bulk_hooks-0.1.281}/README.md +0 -0
- {django_bulk_hooks-0.1.279 → django_bulk_hooks-0.1.281}/django_bulk_hooks/__init__.py +0 -0
- {django_bulk_hooks-0.1.279 → django_bulk_hooks-0.1.281}/django_bulk_hooks/conditions.py +0 -0
- {django_bulk_hooks-0.1.279 → django_bulk_hooks-0.1.281}/django_bulk_hooks/constants.py +0 -0
- {django_bulk_hooks-0.1.279 → django_bulk_hooks-0.1.281}/django_bulk_hooks/context.py +0 -0
- {django_bulk_hooks-0.1.279 → django_bulk_hooks-0.1.281}/django_bulk_hooks/decorators.py +0 -0
- {django_bulk_hooks-0.1.279 → django_bulk_hooks-0.1.281}/django_bulk_hooks/engine.py +0 -0
- {django_bulk_hooks-0.1.279 → django_bulk_hooks-0.1.281}/django_bulk_hooks/enums.py +0 -0
- {django_bulk_hooks-0.1.279 → django_bulk_hooks-0.1.281}/django_bulk_hooks/handler.py +0 -0
- {django_bulk_hooks-0.1.279 → django_bulk_hooks-0.1.281}/django_bulk_hooks/manager.py +0 -0
- {django_bulk_hooks-0.1.279 → django_bulk_hooks-0.1.281}/django_bulk_hooks/models.py +0 -0
- {django_bulk_hooks-0.1.279 → django_bulk_hooks-0.1.281}/django_bulk_hooks/priority.py +0 -0
- {django_bulk_hooks-0.1.279 → django_bulk_hooks-0.1.281}/django_bulk_hooks/registry.py +0 -0
|
@@ -1722,9 +1722,12 @@ class HookQuerySetMixin:
|
|
|
1722
1722
|
parent_update_fields = kwargs.get("update_fields")
|
|
1723
1723
|
if parent_update_fields:
|
|
1724
1724
|
# Only include fields that exist in the parent model
|
|
1725
|
-
parent_model_fields = {
|
|
1725
|
+
parent_model_fields = {
|
|
1726
|
+
field.name for field in model_class._meta.local_fields
|
|
1727
|
+
}
|
|
1726
1728
|
filtered_update_fields = [
|
|
1727
|
-
field
|
|
1729
|
+
field
|
|
1730
|
+
for field in parent_update_fields
|
|
1728
1731
|
if field in parent_model_fields
|
|
1729
1732
|
]
|
|
1730
1733
|
parent_obj.save(update_fields=filtered_update_fields)
|
|
@@ -1770,16 +1773,47 @@ class HookQuerySetMixin:
|
|
|
1770
1773
|
current_parent = parent_obj
|
|
1771
1774
|
parent_objects_map[id(obj)] = parent_instances
|
|
1772
1775
|
|
|
1773
|
-
# Step 2:
|
|
1776
|
+
# Step 2: Handle child objects - create new ones and update existing ones
|
|
1774
1777
|
child_model = inheritance_chain[-1]
|
|
1775
1778
|
all_child_objects = []
|
|
1779
|
+
existing_child_objects = []
|
|
1780
|
+
|
|
1776
1781
|
for obj in batch:
|
|
1777
|
-
|
|
1778
|
-
obj, child_model, parent_objects_map.get(id(obj), {})
|
|
1779
|
-
)
|
|
1780
|
-
all_child_objects.append(child_obj)
|
|
1782
|
+
is_existing_record = obj in existing_records_list
|
|
1781
1783
|
|
|
1782
|
-
|
|
1784
|
+
if is_existing_record:
|
|
1785
|
+
# For existing records, update the child object
|
|
1786
|
+
child_obj = self._create_child_instance(
|
|
1787
|
+
obj, child_model, parent_objects_map.get(id(obj), {})
|
|
1788
|
+
)
|
|
1789
|
+
existing_child_objects.append(child_obj)
|
|
1790
|
+
else:
|
|
1791
|
+
# For new records, create the child object
|
|
1792
|
+
child_obj = self._create_child_instance(
|
|
1793
|
+
obj, child_model, parent_objects_map.get(id(obj), {})
|
|
1794
|
+
)
|
|
1795
|
+
all_child_objects.append(child_obj)
|
|
1796
|
+
|
|
1797
|
+
# Step 2.5: Update existing child objects
|
|
1798
|
+
if existing_child_objects:
|
|
1799
|
+
for child_obj in existing_child_objects:
|
|
1800
|
+
# Filter update_fields to only include fields that exist in the child model
|
|
1801
|
+
child_update_fields = kwargs.get("update_fields")
|
|
1802
|
+
if child_update_fields:
|
|
1803
|
+
# Only include fields that exist in the child model
|
|
1804
|
+
child_model_fields = {
|
|
1805
|
+
field.name for field in child_model._meta.local_fields
|
|
1806
|
+
}
|
|
1807
|
+
filtered_child_update_fields = [
|
|
1808
|
+
field
|
|
1809
|
+
for field in child_update_fields
|
|
1810
|
+
if field in child_model_fields
|
|
1811
|
+
]
|
|
1812
|
+
child_obj.save(update_fields=filtered_child_update_fields)
|
|
1813
|
+
else:
|
|
1814
|
+
child_obj.save()
|
|
1815
|
+
|
|
1816
|
+
# Step 2.6: Use Django's internal bulk_create infrastructure for new child objects
|
|
1783
1817
|
if all_child_objects:
|
|
1784
1818
|
# Get the base manager's queryset
|
|
1785
1819
|
base_qs = child_model._base_manager.using(self.db)
|
|
@@ -1841,12 +1875,21 @@ class HookQuerySetMixin:
|
|
|
1841
1875
|
|
|
1842
1876
|
# Step 3: Update original objects with generated PKs and state
|
|
1843
1877
|
pk_field_name = child_model._meta.pk.name
|
|
1878
|
+
|
|
1879
|
+
# Handle new objects
|
|
1844
1880
|
for orig_obj, child_obj in zip(batch, all_child_objects):
|
|
1845
1881
|
child_pk = getattr(child_obj, pk_field_name)
|
|
1846
1882
|
setattr(orig_obj, pk_field_name, child_pk)
|
|
1847
1883
|
orig_obj._state.adding = False
|
|
1848
1884
|
orig_obj._state.db = self.db
|
|
1849
1885
|
|
|
1886
|
+
# Handle existing objects (they already have PKs, just update state)
|
|
1887
|
+
for orig_obj in batch:
|
|
1888
|
+
is_existing_record = orig_obj in existing_records_list
|
|
1889
|
+
if is_existing_record:
|
|
1890
|
+
orig_obj._state.adding = False
|
|
1891
|
+
orig_obj._state.db = self.db
|
|
1892
|
+
|
|
1850
1893
|
return batch
|
|
1851
1894
|
|
|
1852
1895
|
def _create_parent_instance(self, source_obj, parent_model, current_parent):
|
|
@@ -1856,7 +1899,22 @@ class HookQuerySetMixin:
|
|
|
1856
1899
|
if hasattr(source_obj, field.name):
|
|
1857
1900
|
value = getattr(source_obj, field.name, None)
|
|
1858
1901
|
if value is not None:
|
|
1859
|
-
|
|
1902
|
+
# Handle foreign key fields properly
|
|
1903
|
+
if (
|
|
1904
|
+
field.is_relation
|
|
1905
|
+
and not field.many_to_many
|
|
1906
|
+
and not field.one_to_many
|
|
1907
|
+
):
|
|
1908
|
+
# For foreign key fields, extract the ID if we have a model instance
|
|
1909
|
+
if hasattr(value, "pk") and value.pk is not None:
|
|
1910
|
+
# Set the foreign key ID field (e.g., loan_account_id)
|
|
1911
|
+
setattr(parent_obj, field.attname, value.pk)
|
|
1912
|
+
else:
|
|
1913
|
+
# If it's already an ID or None, use it as-is
|
|
1914
|
+
setattr(parent_obj, field.attname, value)
|
|
1915
|
+
else:
|
|
1916
|
+
# For non-relation fields, copy the value directly
|
|
1917
|
+
setattr(parent_obj, field.name, value)
|
|
1860
1918
|
if current_parent is not None:
|
|
1861
1919
|
for field in parent_model._meta.local_fields:
|
|
1862
1920
|
if (
|
|
@@ -1889,7 +1947,22 @@ class HookQuerySetMixin:
|
|
|
1889
1947
|
if hasattr(source_obj, field.name):
|
|
1890
1948
|
value = getattr(source_obj, field.name, None)
|
|
1891
1949
|
if value is not None:
|
|
1892
|
-
|
|
1950
|
+
# Handle foreign key fields properly
|
|
1951
|
+
if (
|
|
1952
|
+
field.is_relation
|
|
1953
|
+
and not field.many_to_many
|
|
1954
|
+
and not field.one_to_many
|
|
1955
|
+
):
|
|
1956
|
+
# For foreign key fields, extract the ID if we have a model instance
|
|
1957
|
+
if hasattr(value, "pk") and value.pk is not None:
|
|
1958
|
+
# Set the foreign key ID field (e.g., loan_account_id)
|
|
1959
|
+
setattr(child_obj, field.attname, value.pk)
|
|
1960
|
+
else:
|
|
1961
|
+
# If it's already an ID or None, use it as-is
|
|
1962
|
+
setattr(child_obj, field.attname, value)
|
|
1963
|
+
else:
|
|
1964
|
+
# For non-relation fields, copy the value directly
|
|
1965
|
+
setattr(child_obj, field.name, value)
|
|
1893
1966
|
|
|
1894
1967
|
# Set parent links for MTI
|
|
1895
1968
|
for parent_model, parent_instance in parent_instances.items():
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
[tool.poetry]
|
|
2
2
|
name = "django-bulk-hooks"
|
|
3
|
-
version = "0.1.
|
|
3
|
+
version = "0.1.281"
|
|
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
|