django-bulk-hooks 0.2.59__py3-none-any.whl → 0.2.61__py3-none-any.whl
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/changeset.py +4 -23
- django_bulk_hooks/helpers.py +145 -0
- django_bulk_hooks/manager.py +28 -8
- django_bulk_hooks/models.py +13 -1
- django_bulk_hooks/operations/analyzer.py +44 -37
- django_bulk_hooks/operations/bulk_executor.py +121 -104
- django_bulk_hooks/operations/coordinator.py +122 -86
- django_bulk_hooks/operations/field_utils.py +141 -1
- django_bulk_hooks/operations/mti_handler.py +25 -33
- django_bulk_hooks/operations/mti_plans.py +6 -2
- django_bulk_hooks/queryset.py +3 -1
- {django_bulk_hooks-0.2.59.dist-info → django_bulk_hooks-0.2.61.dist-info}/METADATA +1 -1
- django_bulk_hooks-0.2.61.dist-info/RECORD +27 -0
- django_bulk_hooks-0.2.59.dist-info/RECORD +0 -27
- {django_bulk_hooks-0.2.59.dist-info → django_bulk_hooks-0.2.61.dist-info}/LICENSE +0 -0
- {django_bulk_hooks-0.2.59.dist-info → django_bulk_hooks-0.2.61.dist-info}/WHEEL +0 -0
|
@@ -91,4 +91,144 @@ def normalize_field_name_to_db(field_name, model_cls):
|
|
|
91
91
|
return field.attname # Returns 'business_id' for 'business' field
|
|
92
92
|
return field_name
|
|
93
93
|
except Exception: # noqa: BLE001
|
|
94
|
-
return field_name
|
|
94
|
+
return field_name
|
|
95
|
+
|
|
96
|
+
|
|
97
|
+
def get_changed_fields(old_obj, new_obj, model_cls, skip_auto_fields=False):
|
|
98
|
+
"""
|
|
99
|
+
Get field names that have changed between two model instances.
|
|
100
|
+
|
|
101
|
+
Uses Django's field.get_prep_value() for proper database-level comparison.
|
|
102
|
+
This is the canonical implementation used by both RecordChange and ModelAnalyzer.
|
|
103
|
+
|
|
104
|
+
Args:
|
|
105
|
+
old_obj: The old model instance
|
|
106
|
+
new_obj: The new model instance
|
|
107
|
+
model_cls: The Django model class
|
|
108
|
+
skip_auto_fields: Whether to skip auto_created fields (default False)
|
|
109
|
+
|
|
110
|
+
Returns:
|
|
111
|
+
Set of field names that have changed
|
|
112
|
+
"""
|
|
113
|
+
changed = set()
|
|
114
|
+
|
|
115
|
+
for field in model_cls._meta.fields:
|
|
116
|
+
# Skip primary key fields - they shouldn't change
|
|
117
|
+
if field.primary_key:
|
|
118
|
+
continue
|
|
119
|
+
|
|
120
|
+
# Optionally skip auto-created fields (for bulk operations)
|
|
121
|
+
if skip_auto_fields and field.auto_created:
|
|
122
|
+
continue
|
|
123
|
+
|
|
124
|
+
old_val = getattr(old_obj, field.name, None)
|
|
125
|
+
new_val = getattr(new_obj, field.name, None)
|
|
126
|
+
|
|
127
|
+
# Use field's get_prep_value for database-ready comparison
|
|
128
|
+
# This handles timezone conversions, type coercions, etc.
|
|
129
|
+
try:
|
|
130
|
+
old_prep = field.get_prep_value(old_val)
|
|
131
|
+
new_prep = field.get_prep_value(new_val)
|
|
132
|
+
if old_prep != new_prep:
|
|
133
|
+
changed.add(field.name)
|
|
134
|
+
except (TypeError, ValueError):
|
|
135
|
+
# Fallback to direct comparison if get_prep_value fails
|
|
136
|
+
if old_val != new_val:
|
|
137
|
+
changed.add(field.name)
|
|
138
|
+
|
|
139
|
+
return changed
|
|
140
|
+
|
|
141
|
+
|
|
142
|
+
def get_auto_fields(model_cls, include_auto_now_add=True):
|
|
143
|
+
"""
|
|
144
|
+
Get auto fields from a model.
|
|
145
|
+
|
|
146
|
+
Args:
|
|
147
|
+
model_cls: Django model class
|
|
148
|
+
include_auto_now_add: Whether to include auto_now_add fields
|
|
149
|
+
|
|
150
|
+
Returns:
|
|
151
|
+
List of field names
|
|
152
|
+
"""
|
|
153
|
+
fields = []
|
|
154
|
+
for field in model_cls._meta.fields:
|
|
155
|
+
if getattr(field, "auto_now", False) or (
|
|
156
|
+
include_auto_now_add and getattr(field, "auto_now_add", False)
|
|
157
|
+
):
|
|
158
|
+
fields.append(field.name)
|
|
159
|
+
return fields
|
|
160
|
+
|
|
161
|
+
|
|
162
|
+
def get_auto_now_only_fields(model_cls):
|
|
163
|
+
"""Get only auto_now fields (excluding auto_now_add)."""
|
|
164
|
+
return get_auto_fields(model_cls, include_auto_now_add=False)
|
|
165
|
+
|
|
166
|
+
|
|
167
|
+
def get_fk_fields(model_cls):
|
|
168
|
+
"""Get foreign key field names for a model."""
|
|
169
|
+
return [field.name for field in model_cls._meta.concrete_fields
|
|
170
|
+
if field.is_relation and not field.many_to_many]
|
|
171
|
+
|
|
172
|
+
|
|
173
|
+
def collect_auto_now_fields_for_inheritance_chain(inheritance_chain):
|
|
174
|
+
"""Collect auto_now fields across an MTI inheritance chain."""
|
|
175
|
+
all_auto_now = set()
|
|
176
|
+
for model_cls in inheritance_chain:
|
|
177
|
+
all_auto_now.update(get_auto_now_only_fields(model_cls))
|
|
178
|
+
return all_auto_now
|
|
179
|
+
|
|
180
|
+
|
|
181
|
+
def handle_auto_now_fields_for_inheritance_chain(models, instances, for_update=True):
|
|
182
|
+
"""
|
|
183
|
+
Unified auto-now field handling for any inheritance chain.
|
|
184
|
+
|
|
185
|
+
This replaces the separate collect/pre_save logic with a single comprehensive
|
|
186
|
+
method that handles collection, pre-saving, and field inclusion for updates.
|
|
187
|
+
|
|
188
|
+
Args:
|
|
189
|
+
models: List of model classes in inheritance chain
|
|
190
|
+
instances: List of model instances to process
|
|
191
|
+
for_update: Whether this is for an update operation (vs create)
|
|
192
|
+
|
|
193
|
+
Returns:
|
|
194
|
+
Set of auto_now field names that should be included in updates
|
|
195
|
+
"""
|
|
196
|
+
all_auto_now_fields = set()
|
|
197
|
+
|
|
198
|
+
for model_cls in models:
|
|
199
|
+
for field in model_cls._meta.local_fields:
|
|
200
|
+
# For updates, only include auto_now (not auto_now_add)
|
|
201
|
+
# For creates, include both
|
|
202
|
+
if getattr(field, "auto_now", False) or (
|
|
203
|
+
not for_update and getattr(field, "auto_now_add", False)
|
|
204
|
+
):
|
|
205
|
+
all_auto_now_fields.add(field.name)
|
|
206
|
+
|
|
207
|
+
# Pre-save the field on instances
|
|
208
|
+
for instance in instances:
|
|
209
|
+
if for_update:
|
|
210
|
+
# For updates, only pre-save auto_now fields
|
|
211
|
+
field.pre_save(instance, add=False)
|
|
212
|
+
else:
|
|
213
|
+
# For creates, pre-save both auto_now and auto_now_add
|
|
214
|
+
field.pre_save(instance, add=True)
|
|
215
|
+
|
|
216
|
+
return all_auto_now_fields
|
|
217
|
+
|
|
218
|
+
|
|
219
|
+
def pre_save_auto_now_fields(objects, inheritance_chain):
|
|
220
|
+
"""Pre-save auto_now fields across inheritance chain."""
|
|
221
|
+
# DEPRECATED: Use handle_auto_now_fields_for_inheritance_chain instead
|
|
222
|
+
auto_now_fields = collect_auto_now_fields_for_inheritance_chain(inheritance_chain)
|
|
223
|
+
|
|
224
|
+
for field_name in auto_now_fields:
|
|
225
|
+
# Find which model has this field
|
|
226
|
+
for model_cls in inheritance_chain:
|
|
227
|
+
try:
|
|
228
|
+
field = model_cls._meta.get_field(field_name)
|
|
229
|
+
if getattr(field, "auto_now", False):
|
|
230
|
+
for obj in objects:
|
|
231
|
+
field.pre_save(obj, add=False)
|
|
232
|
+
break
|
|
233
|
+
except Exception:
|
|
234
|
+
continue
|
|
@@ -217,6 +217,11 @@ class MTIHandler:
|
|
|
217
217
|
child_obj = self._create_child_instance_template(obj, inheritance_chain[-1])
|
|
218
218
|
child_objects.append(child_obj)
|
|
219
219
|
|
|
220
|
+
# Pre-compute child-specific fields for execution efficiency
|
|
221
|
+
from django_bulk_hooks.helpers import get_fields_for_model, filter_field_names_for_model
|
|
222
|
+
child_unique_fields = get_fields_for_model(inheritance_chain[-1], unique_fields or [])
|
|
223
|
+
child_update_fields = get_fields_for_model(inheritance_chain[-1], update_fields or [])
|
|
224
|
+
|
|
220
225
|
return MTICreatePlan(
|
|
221
226
|
inheritance_chain=inheritance_chain,
|
|
222
227
|
parent_levels=parent_levels,
|
|
@@ -228,6 +233,8 @@ class MTIHandler:
|
|
|
228
233
|
update_conflicts=update_conflicts,
|
|
229
234
|
unique_fields=unique_fields or [],
|
|
230
235
|
update_fields=update_fields or [],
|
|
236
|
+
child_unique_fields=child_unique_fields,
|
|
237
|
+
child_update_fields=child_update_fields,
|
|
231
238
|
)
|
|
232
239
|
|
|
233
240
|
def _build_parent_levels(
|
|
@@ -458,14 +465,13 @@ class MTIHandler:
|
|
|
458
465
|
if hasattr(source_obj._state, "db"):
|
|
459
466
|
parent_obj._state.db = source_obj._state.db
|
|
460
467
|
|
|
461
|
-
#
|
|
462
|
-
|
|
463
|
-
|
|
464
|
-
|
|
465
|
-
|
|
466
|
-
|
|
467
|
-
|
|
468
|
-
field.pre_save(parent_obj, add=True)
|
|
468
|
+
# Use unified auto-now field handling
|
|
469
|
+
from django_bulk_hooks.operations.field_utils import handle_auto_now_fields_for_inheritance_chain
|
|
470
|
+
|
|
471
|
+
# Handle auto fields for this single parent model
|
|
472
|
+
handle_auto_now_fields_for_inheritance_chain(
|
|
473
|
+
[parent_model], [parent_obj], for_update=False, # MTI create is like insert
|
|
474
|
+
)
|
|
469
475
|
|
|
470
476
|
return parent_obj
|
|
471
477
|
|
|
@@ -516,14 +522,13 @@ class MTIHandler:
|
|
|
516
522
|
if hasattr(source_obj._state, "db"):
|
|
517
523
|
child_obj._state.db = source_obj._state.db
|
|
518
524
|
|
|
519
|
-
#
|
|
520
|
-
|
|
521
|
-
|
|
522
|
-
|
|
523
|
-
|
|
524
|
-
|
|
525
|
-
|
|
526
|
-
field.pre_save(child_obj, add=True)
|
|
525
|
+
# Use unified auto-now field handling
|
|
526
|
+
from django_bulk_hooks.operations.field_utils import handle_auto_now_fields_for_inheritance_chain
|
|
527
|
+
|
|
528
|
+
# Handle auto fields for this single child model
|
|
529
|
+
handle_auto_now_fields_for_inheritance_chain(
|
|
530
|
+
[child_model], [child_obj], for_update=False, # MTI create is like insert
|
|
531
|
+
)
|
|
527
532
|
|
|
528
533
|
return child_obj
|
|
529
534
|
|
|
@@ -537,7 +542,7 @@ class MTIHandler:
|
|
|
537
542
|
|
|
538
543
|
Args:
|
|
539
544
|
objs: List of model instances to update
|
|
540
|
-
fields: List of field names to update
|
|
545
|
+
fields: List of field names to update (auto_now fields already included by executor)
|
|
541
546
|
batch_size: Number of objects per batch
|
|
542
547
|
|
|
543
548
|
Returns:
|
|
@@ -555,28 +560,15 @@ class MTIHandler:
|
|
|
555
560
|
|
|
556
561
|
batch_size = batch_size or len(objs)
|
|
557
562
|
|
|
558
|
-
#
|
|
559
|
-
|
|
560
|
-
for model in inheritance_chain:
|
|
561
|
-
for field in model._meta.local_fields:
|
|
562
|
-
if getattr(field, "auto_now", False):
|
|
563
|
-
field.pre_save(obj, add=False)
|
|
564
|
-
|
|
565
|
-
# Add auto_now fields to update list
|
|
566
|
-
auto_now_fields = set()
|
|
567
|
-
for model in inheritance_chain:
|
|
568
|
-
for field in model._meta.local_fields:
|
|
569
|
-
if getattr(field, "auto_now", False):
|
|
570
|
-
auto_now_fields.add(field.name)
|
|
571
|
-
|
|
572
|
-
all_fields = list(fields) + list(auto_now_fields)
|
|
563
|
+
# Note: auto_now fields are already handled by executor.bulk_update()
|
|
564
|
+
# which calls pre_save() and includes them in the fields list
|
|
573
565
|
|
|
574
566
|
# Group fields by model
|
|
575
567
|
field_groups = []
|
|
576
568
|
for model_idx, model in enumerate(inheritance_chain):
|
|
577
569
|
model_fields = []
|
|
578
570
|
|
|
579
|
-
for field_name in
|
|
571
|
+
for field_name in fields:
|
|
580
572
|
try:
|
|
581
573
|
field = self.model_cls._meta.get_field(field_name)
|
|
582
574
|
if field in model._meta.local_fields:
|
|
@@ -49,8 +49,10 @@ class MTICreatePlan:
|
|
|
49
49
|
batch_size: Batch size for operations
|
|
50
50
|
existing_record_ids: Set of id() of original objects that represent existing DB records
|
|
51
51
|
update_conflicts: Whether this is an upsert operation
|
|
52
|
-
unique_fields: Fields used for conflict detection
|
|
53
|
-
update_fields: Fields to update on conflict
|
|
52
|
+
unique_fields: Fields used for conflict detection (original, unfiltered)
|
|
53
|
+
update_fields: Fields to update on conflict (original, unfiltered)
|
|
54
|
+
child_unique_fields: Pre-filtered field objects for child table conflict detection
|
|
55
|
+
child_update_fields: Pre-filtered field objects for child table updates
|
|
54
56
|
"""
|
|
55
57
|
|
|
56
58
|
inheritance_chain: list[Any]
|
|
@@ -63,6 +65,8 @@ class MTICreatePlan:
|
|
|
63
65
|
update_conflicts: bool = False
|
|
64
66
|
unique_fields: list[str] = field(default_factory=list)
|
|
65
67
|
update_fields: list[str] = field(default_factory=list)
|
|
68
|
+
child_unique_fields: list = field(default_factory=list) # Field objects for child table
|
|
69
|
+
child_update_fields: list = field(default_factory=list) # Field objects for child table
|
|
66
70
|
|
|
67
71
|
|
|
68
72
|
@dataclass
|
django_bulk_hooks/queryset.py
CHANGED
|
@@ -11,6 +11,8 @@ import logging
|
|
|
11
11
|
from django.db import models
|
|
12
12
|
from django.db import transaction
|
|
13
13
|
|
|
14
|
+
from django_bulk_hooks.helpers import extract_pks
|
|
15
|
+
|
|
14
16
|
logger = logging.getLogger(__name__)
|
|
15
17
|
|
|
16
18
|
|
|
@@ -148,7 +150,7 @@ class HookQuerySet(models.QuerySet):
|
|
|
148
150
|
Tuple of (count, details dict)
|
|
149
151
|
"""
|
|
150
152
|
# Filter queryset to only these objects
|
|
151
|
-
pks =
|
|
153
|
+
pks = extract_pks(objs)
|
|
152
154
|
if not pks:
|
|
153
155
|
return 0
|
|
154
156
|
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
django_bulk_hooks/__init__.py,sha256=ujBvX-GY4Pg4ACBh7RXm_MOmi2eAowf5s7pG2SXWdpo,2276
|
|
2
|
+
django_bulk_hooks/changeset.py,sha256=opWqb_x-_9KaMsUJc7lI3wScWLHn2Yhe7hB-ngFCBp0,6731
|
|
3
|
+
django_bulk_hooks/conditions.py,sha256=v2DMFmWI7bppBQw5qdbO5CmQRN_QtUwnBjcyKBJLLbw,8030
|
|
4
|
+
django_bulk_hooks/constants.py,sha256=PxpEETaO6gdENcTPoXS586lerGKVP3nmjpDvOkmhYxI,509
|
|
5
|
+
django_bulk_hooks/context.py,sha256=mqaC5-yESDTA5ruI7fuXlt8qSgKuOFp0mjq7h1-4HdQ,1926
|
|
6
|
+
django_bulk_hooks/decorators.py,sha256=P7cvzFgORJRW-YQHNAxNXqQOP9OywBmA7Rz9kiJoxUk,12237
|
|
7
|
+
django_bulk_hooks/dispatcher.py,sha256=CiKYe5ecUPu5TYUZq8ToaRT40TkLc5l5mczgf5XDzGA,8217
|
|
8
|
+
django_bulk_hooks/enums.py,sha256=Zo8_tJzuzZ2IKfVc7gZ-0tWPT8q1QhqZbAyoh9ZVJbs,381
|
|
9
|
+
django_bulk_hooks/factory.py,sha256=ezrVM5U023KZqOBbJXb6lYUP-pE7WJmi8Olh2Ew-7RA,18085
|
|
10
|
+
django_bulk_hooks/handler.py,sha256=38ejMdQ9reYA07_XQ9tC8xv0lW3amO-m8gPzuRNOyj0,4200
|
|
11
|
+
django_bulk_hooks/helpers.py,sha256=e14aYE1lKaj8-krFclY_WfJF2uWQpblfsl5hqsW-dxY,7800
|
|
12
|
+
django_bulk_hooks/manager.py,sha256=g11g1MZ4DJGIM4prYLpYLejTsz0YkYPWeoxWA4dcgYk,4596
|
|
13
|
+
django_bulk_hooks/models.py,sha256=9uh7leV3EEnTWkNKNqT1xevamPTczRhW7KbnIHraBlk,2969
|
|
14
|
+
django_bulk_hooks/operations/__init__.py,sha256=BtJYjmRhe_sScivLsniDaZmBkm0ZLvcmzXFKL7QY2Xg,550
|
|
15
|
+
django_bulk_hooks/operations/analyzer.py,sha256=wO-LUgGExE8y3fb25kdfpbj_KdSIW8fd4QFp0Os8Muk,10679
|
|
16
|
+
django_bulk_hooks/operations/bulk_executor.py,sha256=byo09_65qQI_Z-7HvIoeWh-fRAFnI6qrWFjDr2Ar8LA,26275
|
|
17
|
+
django_bulk_hooks/operations/coordinator.py,sha256=d7DD_CMUA4yeUJeJueBOQ9LrJFFj3emVx56hG1Ju5Xg,33787
|
|
18
|
+
django_bulk_hooks/operations/field_utils.py,sha256=M1HfBj5EK5c6SbOmkVT9s6u_SEOh_N4bheytm5jBD4o,7980
|
|
19
|
+
django_bulk_hooks/operations/mti_handler.py,sha256=LbmbAzowfaQePWjjryHJxogvyDZ4GTL176gc6ezKVYA,25829
|
|
20
|
+
django_bulk_hooks/operations/mti_plans.py,sha256=Vl0lV7AuhmovI0_qcD73KairyPy73l36fJYk8wRBh2g,3770
|
|
21
|
+
django_bulk_hooks/operations/record_classifier.py,sha256=kqML4aO11X9K3SSJ5DUlUukwI172j_Tk12Kr77ee8q8,7065
|
|
22
|
+
django_bulk_hooks/queryset.py,sha256=8xdA3jV6SeEGzW-av346I85Kq1N1uqt178aEh8vm8v8,5568
|
|
23
|
+
django_bulk_hooks/registry.py,sha256=uum5jhGI3TPaoiXuA1MdBdu4gbE3rQGGwQ5YDjiMcjk,7949
|
|
24
|
+
django_bulk_hooks-0.2.61.dist-info/LICENSE,sha256=dguKIcbDGeZD-vXWdLyErPUALYOvtX_fO4Zjhq481uk,1088
|
|
25
|
+
django_bulk_hooks-0.2.61.dist-info/METADATA,sha256=UxXjcApyuPWulCJWCm9LJGeI6Krh7bwb8mdOsVMfmc0,9265
|
|
26
|
+
django_bulk_hooks-0.2.61.dist-info/WHEEL,sha256=b4K_helf-jlQoXBBETfwnf4B04YC67LOev0jo4fX5m8,88
|
|
27
|
+
django_bulk_hooks-0.2.61.dist-info/RECORD,,
|
|
@@ -1,27 +0,0 @@
|
|
|
1
|
-
django_bulk_hooks/__init__.py,sha256=ujBvX-GY4Pg4ACBh7RXm_MOmi2eAowf5s7pG2SXWdpo,2276
|
|
2
|
-
django_bulk_hooks/changeset.py,sha256=wU6wckJEQ_hG5UZq_9g_kWODoKwEj99JrtacVUQ9BxA,7445
|
|
3
|
-
django_bulk_hooks/conditions.py,sha256=v2DMFmWI7bppBQw5qdbO5CmQRN_QtUwnBjcyKBJLLbw,8030
|
|
4
|
-
django_bulk_hooks/constants.py,sha256=PxpEETaO6gdENcTPoXS586lerGKVP3nmjpDvOkmhYxI,509
|
|
5
|
-
django_bulk_hooks/context.py,sha256=mqaC5-yESDTA5ruI7fuXlt8qSgKuOFp0mjq7h1-4HdQ,1926
|
|
6
|
-
django_bulk_hooks/decorators.py,sha256=P7cvzFgORJRW-YQHNAxNXqQOP9OywBmA7Rz9kiJoxUk,12237
|
|
7
|
-
django_bulk_hooks/dispatcher.py,sha256=CiKYe5ecUPu5TYUZq8ToaRT40TkLc5l5mczgf5XDzGA,8217
|
|
8
|
-
django_bulk_hooks/enums.py,sha256=Zo8_tJzuzZ2IKfVc7gZ-0tWPT8q1QhqZbAyoh9ZVJbs,381
|
|
9
|
-
django_bulk_hooks/factory.py,sha256=ezrVM5U023KZqOBbJXb6lYUP-pE7WJmi8Olh2Ew-7RA,18085
|
|
10
|
-
django_bulk_hooks/handler.py,sha256=38ejMdQ9reYA07_XQ9tC8xv0lW3amO-m8gPzuRNOyj0,4200
|
|
11
|
-
django_bulk_hooks/helpers.py,sha256=Nw8eXryLUUquW7AgiuKp0PQT3Pq6HAHsdP-xAtqhmjA,3216
|
|
12
|
-
django_bulk_hooks/manager.py,sha256=3mFzB0ZzHHeXWdKGObZD_H0NlskHJc8uYBF69KKdAXU,4068
|
|
13
|
-
django_bulk_hooks/models.py,sha256=4Vvi2LiGP0g4j08a5liqBROfsO8Wd_ermBoyjKwfrPU,2512
|
|
14
|
-
django_bulk_hooks/operations/__init__.py,sha256=BtJYjmRhe_sScivLsniDaZmBkm0ZLvcmzXFKL7QY2Xg,550
|
|
15
|
-
django_bulk_hooks/operations/analyzer.py,sha256=wAG8sAG9NwfwNqG9z81VfGR7AANDzRmMGE_o82MWji4,10689
|
|
16
|
-
django_bulk_hooks/operations/bulk_executor.py,sha256=Y-wkvuV_X-SZmI965JVrrtwbzPZVggUfy8mR1pzP9d0,27048
|
|
17
|
-
django_bulk_hooks/operations/coordinator.py,sha256=1Ka5eZJXTFjx3tr-BD6Tr350Y2T57SUOX3vjagBYBvM,32193
|
|
18
|
-
django_bulk_hooks/operations/field_utils.py,sha256=Tvr5bcZLG8imH-r2S85oui1Cbw6hGv3VtuIMn4OvsU4,2895
|
|
19
|
-
django_bulk_hooks/operations/mti_handler.py,sha256=173jghcxCE5UEZxM1QJRS-lWg0-KJxCQCbWHVKppIEM,26000
|
|
20
|
-
django_bulk_hooks/operations/mti_plans.py,sha256=7STQ2oA2ZT8cEG3-t-6xciRAdf7OeSf0gRLXR_BRG-Q,3363
|
|
21
|
-
django_bulk_hooks/operations/record_classifier.py,sha256=kqML4aO11X9K3SSJ5DUlUukwI172j_Tk12Kr77ee8q8,7065
|
|
22
|
-
django_bulk_hooks/queryset.py,sha256=aQitlbexcVnmeAdc0jtO3hci39p4QEu4srQPEzozy5s,5546
|
|
23
|
-
django_bulk_hooks/registry.py,sha256=uum5jhGI3TPaoiXuA1MdBdu4gbE3rQGGwQ5YDjiMcjk,7949
|
|
24
|
-
django_bulk_hooks-0.2.59.dist-info/LICENSE,sha256=dguKIcbDGeZD-vXWdLyErPUALYOvtX_fO4Zjhq481uk,1088
|
|
25
|
-
django_bulk_hooks-0.2.59.dist-info/METADATA,sha256=Zqy1xIlJ4pSLl-rxnjA96tNhdgomhT21cnHI7Z9ZbE8,9265
|
|
26
|
-
django_bulk_hooks-0.2.59.dist-info/WHEEL,sha256=b4K_helf-jlQoXBBETfwnf4B04YC67LOev0jo4fX5m8,88
|
|
27
|
-
django_bulk_hooks-0.2.59.dist-info/RECORD,,
|
|
File without changes
|
|
File without changes
|