Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit4702b36

Browse files
committed
Fixed #27380 -- Added "raw" argument to m2m_changed signals.
1 parent12d5744 commit4702b36

File tree

7 files changed

+171
-15
lines changed

7 files changed

+171
-15
lines changed

‎django/core/serializers/base.py‎

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -290,11 +290,11 @@ def __repr__(self):
290290
defsave(self,save_m2m=True,using=None,**kwargs):
291291
# Call save on the Model baseclass directly. This bypasses any
292292
# model-defined save. The save is also forced to be raw.
293-
# raw=True is passed to any pre/post_save signals.
293+
# raw=True is passed to any pre/post_saveand m2m_changedsignals.
294294
models.Model.save_base(self.object,using=using,raw=True,**kwargs)
295295
ifself.m2m_dataandsave_m2m:
296296
foraccessor_name,object_listinself.m2m_data.items():
297-
getattr(self.object,accessor_name).set(object_list)
297+
getattr(self.object,accessor_name).set_base(object_list,raw=True)
298298

299299
# prevent a second (possibly accidental) call to save() from saving
300300
# the m2m data twice.

‎django/db/models/fields/related_descriptors.py‎

Lines changed: 21 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1262,7 +1262,7 @@ def count(self):
12621262
else:
12631263
returnsuper().count()
12641264

1265-
def_add_base(self,*objs,through_defaults=None,using=None):
1265+
def_add_base(self,*objs,through_defaults=None,using=None,raw=False):
12661266
db=usingorrouter.db_for_write(self.through,instance=self.instance)
12671267
withtransaction.atomic(using=db,savepoint=False):
12681268
self._add_items(
@@ -1271,6 +1271,7 @@ def _add_base(self, *objs, through_defaults=None, using=None):
12711271
*objs,
12721272
through_defaults=through_defaults,
12731273
using=db,
1274+
raw=raw,
12741275
)
12751276
# If this is a symmetrical m2m relation to self, add the mirror
12761277
# entry in the m2m table.
@@ -1281,6 +1282,7 @@ def _add_base(self, *objs, through_defaults=None, using=None):
12811282
*objs,
12821283
through_defaults=through_defaults,
12831284
using=db,
1285+
raw=raw,
12841286
)
12851287

12861288
defadd(self,*objs,through_defaults=None):
@@ -1297,10 +1299,10 @@ async def aadd(self, *objs, through_defaults=None):
12971299

12981300
aadd.alters_data=True
12991301

1300-
def_remove_base(self,*objs,using=None):
1302+
def_remove_base(self,*objs,using=None,raw=False):
13011303
db=usingorrouter.db_for_write(self.through,instance=self.instance)
13021304
self._remove_items(
1303-
self.source_field_name,self.target_field_name,*objs,using=db
1305+
self.source_field_name,self.target_field_name,*objs,using=db,raw=raw
13041306
)
13051307

13061308
defremove(self,*objs):
@@ -1315,7 +1317,7 @@ async def aremove(self, *objs):
13151317

13161318
aremove.alters_data=True
13171319

1318-
def_clear_base(self,using=None):
1320+
def_clear_base(self,using=None,raw=False):
13191321
db=usingorrouter.db_for_write(self.through,instance=self.instance)
13201322
withtransaction.atomic(using=db,savepoint=False):
13211323
signals.m2m_changed.send(
@@ -1326,6 +1328,7 @@ def _clear_base(self, using=None):
13261328
model=self.model,
13271329
pk_set=None,
13281330
using=db,
1331+
raw=raw,
13291332
)
13301333
filters=self._build_remove_filters(super().get_queryset().using(db))
13311334
self.through._default_manager.using(db).filter(filters).delete()
@@ -1338,6 +1341,7 @@ def _clear_base(self, using=None):
13381341
model=self.model,
13391342
pk_set=None,
13401343
using=db,
1344+
raw=raw,
13411345
)
13421346

13431347
defclear(self):
@@ -1352,7 +1356,7 @@ async def aclear(self):
13521356

13531357
aclear.alters_data=True
13541358

1355-
defset_base(self,objs,*,clear=False,through_defaults=None):
1359+
defset_base(self,objs,*,clear=False,through_defaults=None,raw=False):
13561360
# Force evaluation of `objs` in case it's a queryset whose value
13571361
# could be affected by `manager.clear()`. Refs #19816.
13581362
objs=tuple(objs)
@@ -1361,8 +1365,10 @@ def set_base(self, objs, *, clear=False, through_defaults=None):
13611365
withtransaction.atomic(using=db,savepoint=False):
13621366
self._remove_prefetched_objects()
13631367
ifclear:
1364-
self._clear_base(using=db)
1365-
self._add_base(*objs,through_defaults=through_defaults,using=db)
1368+
self._clear_base(using=db,raw=raw)
1369+
self._add_base(
1370+
*objs,through_defaults=through_defaults,using=db,raw=raw
1371+
)
13661372
else:
13671373
old_ids=set(
13681374
self.using(db).values_list(
@@ -1382,9 +1388,9 @@ def set_base(self, objs, *, clear=False, through_defaults=None):
13821388
else:
13831389
new_objs.append(obj)
13841390

1385-
self._remove_base(*old_ids,using=db)
1391+
self._remove_base(*old_ids,using=db,raw=raw)
13861392
self._add_base(
1387-
*new_objs,through_defaults=through_defaults,using=db
1393+
*new_objs,through_defaults=through_defaults,using=db,raw=raw
13881394
)
13891395

13901396
defset(self,objs,*,clear=False,through_defaults=None):
@@ -1545,6 +1551,7 @@ def _add_items(
15451551
*objs,
15461552
through_defaults=None,
15471553
using=None,
1554+
raw=False,
15481555
):
15491556
# source_field_name: the PK fieldname in join table for the source
15501557
# object target_field_name: the PK fieldname in join table for the
@@ -1587,6 +1594,7 @@ def _add_items(
15871594
model=self.model,
15881595
pk_set=missing_target_ids,
15891596
using=db,
1597+
raw=raw,
15901598
)
15911599
# Add the ones that aren't there already.
15921600
self.through._default_manager.using(db).bulk_create(
@@ -1612,10 +1620,11 @@ def _add_items(
16121620
model=self.model,
16131621
pk_set=missing_target_ids,
16141622
using=db,
1623+
raw=raw,
16151624
)
16161625

16171626
def_remove_items(
1618-
self,source_field_name,target_field_name,*objs,using=None
1627+
self,source_field_name,target_field_name,*objs,using=None,raw=False
16191628
):
16201629
# source_field_name: the PK colname in join table for the source
16211630
# object target_field_name: the PK colname in join table for the
@@ -1644,6 +1653,7 @@ def _remove_items(
16441653
model=self.model,
16451654
pk_set=old_ids,
16461655
using=db,
1656+
raw=raw,
16471657
)
16481658
target_model_qs=super().get_queryset()
16491659
iftarget_model_qs._has_filters():
@@ -1663,6 +1673,7 @@ def _remove_items(
16631673
model=self.model,
16641674
pk_set=old_ids,
16651675
using=db,
1676+
raw=raw,
16661677
)
16671678

16681679
returnManyRelatedManager

‎docs/ref/signals.txt‎

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -303,6 +303,15 @@ Arguments sent with this signal:
303303
``using``
304304
The database alias being used.
305305

306+
``raw``
307+
308+
.. versionadded:: 6.1
309+
310+
A boolean; ``True`` if the model is saved exactly as presented
311+
(i.e. when loading a :ref:`fixture <fixtures-explanation>`). One should not
312+
query/modify other records in the database as the database might not be in
313+
a consistent state yet.
314+
306315
For example, if a ``Pizza`` can have multiple ``Topping`` objects, modeled
307316
like this::
308317

@@ -357,6 +366,8 @@ Argument Value
357366
``pk_set`` ``{t.id}`` (since only ``Topping t`` was added to the relation)
358367

359368
``using`` ``"default"`` (since the default router sends writes here)
369+
370+
``raw`` ``False`` (since it is not loaded from a fixture)
360371
============== ============================================================
361372

362373
And if we would then do something like this:
@@ -387,6 +398,8 @@ Argument Value
387398
relation)
388399

389400
``using`` ``"default"`` (since the default router sends writes here)
401+
402+
``raw`` ``False`` (since it is not loaded from a fixture)
390403
============== ============================================================
391404

392405
``class_prepared``

‎docs/releases/6.1.txt‎

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -237,6 +237,10 @@ Management Commands
237237
``suggest_on_error`` argument to ``True`` by default on Python 3.14, enabling
238238
suggestions for mistyped subcommand names and argument choices.
239239

240+
* The :djadmin:`loaddata` command now calls
241+
:data:`~django.db.models.signals.m2m_changed` signals with ``raw=True`` when
242+
loading fixtures.
243+
240244
Migrations
241245
~~~~~~~~~~
242246

‎docs/topics/db/fixtures.txt‎

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -118,8 +118,9 @@ How fixtures are saved to the database
118118

119119
When fixture files are processed, the data is saved to the database as is.
120120
Model defined :meth:`~django.db.models.Model.save` methods are not called, and
121-
any :data:`~django.db.models.signals.pre_save` or
122-
:data:`~django.db.models.signals.post_save` signals will be called with
121+
any :data:`~django.db.models.signals.pre_save`,
122+
:data:`~django.db.models.signals.post_save`, or
123+
:data:`~django.db.models.signals.m2m_changed` signals will be called with
123124
``raw=True`` since the instance only contains attributes that are local to the
124125
model. You may, for example, want to disable handlers that access
125126
related fields that aren't present during fixture loading and would otherwise
@@ -163,6 +164,10 @@ You could also write a decorator to encapsulate this logic::
163164
Just be aware that this logic will disable the signals whenever fixtures are
164165
deserialized, not just during :djadmin:`loaddata`.
165166

167+
.. versionchanged:: 6.1
168+
169+
The ``raw`` argument was added to ``m2m_changed`` signals.
170+
166171
Compressed fixtures
167172
===================
168173

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp