@@ -65,6 +65,7 @@ def bulk_create_with_history(
6565 default_user = None ,
6666 default_change_reason = None ,
6767 default_date = None ,
68+ custom_historical_attrs = None ,
6869):
6970 """
7071 Bulk create the objects specified by objs while also bulk creating
@@ -81,6 +82,8 @@ def bulk_create_with_history(
8182 in each historical record
8283 :param default_date: Optional date to specify as the history_date in each historical
8384 record
85+ :param custom_historical_attrs: Optional dict of field `name`:`value` to specify
86+ values for custom fields
8487 :return: List of objs with IDs
8588 """
8689 # Exclude ManyToManyFields because they end up as invalid kwargs to
@@ -106,6 +109,7 @@ def bulk_create_with_history(
106109 default_user = default_user ,
107110 default_change_reason = default_change_reason ,
108111 default_date = default_date ,
112+ custom_historical_attrs = custom_historical_attrs ,
109113 )
110114 if second_transaction_required :
111115 with transaction .atomic (savepoint = False ):
@@ -143,6 +147,7 @@ def bulk_create_with_history(
143147 default_user = default_user ,
144148 default_change_reason = default_change_reason ,
145149 default_date = default_date ,
150+ custom_historical_attrs = custom_historical_attrs ,
146151 )
147152 objs_with_id = obj_list
148153 return objs_with_id
@@ -157,13 +162,15 @@ def bulk_update_with_history(
157162 default_change_reason = None ,
158163 default_date = None ,
159164 manager = None ,
165+ custom_historical_attrs = None ,
160166):
161167 """
162168 Bulk update the objects specified by objs while also bulk creating
163169 their history (all in one transaction).
164170 :param objs: List of objs of type model to be updated
165171 :param model: Model class that should be updated
166- :param fields: The fields that are updated
172+ :param fields: The fields that are updated. If empty, no model objects will be
173+ changed, but history records will still be created.
167174 :param batch_size: Number of objects that should be updated in each batch
168175 :param default_user: Optional user to specify as the history_user in each historical
169176 record
@@ -173,6 +180,8 @@ def bulk_update_with_history(
173180 record
174181 :param manager: Optional model manager to use for the model instead of the default
175182 manager
183+ :param custom_historical_attrs: Optional dict of field `name`:`value` to specify
184+ values for custom fields
176185 :return: The number of model rows updated, not including any history objects
177186 """
178187 history_manager = get_history_manager_for_model (model )
@@ -181,14 +190,23 @@ def bulk_update_with_history(
181190 raise AlternativeManagerError ("The given manager does not belong to the model." )
182191
183192 with transaction .atomic (savepoint = False ):
184- rows_updated = model_manager .bulk_update (objs , fields , batch_size = batch_size )
193+ if not fields :
194+ # Allow not passing any fields if the user wants to bulk-create history
195+ # records - e.g. with `custom_historical_attrs` provided
196+ # (Calling `bulk_update()` with no fields would have raised an error)
197+ rows_updated = 0
198+ else :
199+ rows_updated = model_manager .bulk_update (
200+ objs , fields , batch_size = batch_size
201+ )
185202 history_manager .bulk_history_create (
186203 objs ,
187204 batch_size = batch_size ,
188205 update = True ,
189206 default_user = default_user ,
190207 default_change_reason = default_change_reason ,
191208 default_date = default_date ,
209+ custom_historical_attrs = custom_historical_attrs ,
192210 )
193211 return rows_updated
194212
0 commit comments