Ticket #13772: 13772.patch
File 13772.patch, 6.9 KB (added by , 14 years ago) |
---|
-
django/db/models/base.py
diff -r 7fca770b5dc2 -r 0c51517ac4a0 django/db/models/base.py
a b 454 454 else: 455 455 meta = cls._meta 456 456 457 pk_val = self._get_pk_val(meta) 458 pk_set = pk_val is not None 459 manager = cls._base_manager 460 record_exists = pk_set and manager.using(using).filter(pk=pk_val).exists() 457 461 if origin and not meta.auto_created: 458 signals.pre_save.send(sender=origin, instance=self, raw=raw, using=using) 462 signals.pre_save.send(sender=origin, instance=self, raw=raw, 463 exists=record_exists, using=using) 459 464 460 465 # If we are in a raw save, save the object exactly as presented. 461 466 # That means that we don't try to be smart about saving attributes … … 484 489 485 490 if not meta.proxy: 486 491 non_pks = [f for f in meta.local_fields if not f.primary_key] 487 488 # First, try an UPDATE. If that doesn't update anything, do an INSERT. 489 pk_val = self._get_pk_val(meta) 490 pk_set = pk_val is not None 491 record_exists = True 492 manager = cls._base_manager 493 if pk_set: 494 # Determine whether a record with the primary key already exists. 495 if (force_update or (not force_insert and 496 manager.using(using).filter(pk=pk_val).exists())): 497 # It does already exist, so do an UPDATE. 498 if force_update or non_pks: 499 values = [(f, None, (raw and getattr(self, f.attname) or f.pre_save(self, False))) for f in non_pks] 500 rows = manager.using(using).filter(pk=pk_val)._update(values) 501 if force_update and not rows: 502 raise DatabaseError("Forced update did not affect any rows.") 503 else: 504 record_exists = False 505 if not pk_set or not record_exists: 492 can_force_update = force_update and pk_set 493 can_update = record_exists and not force_insert 494 if can_force_update or (can_update and non_pks): 495 values = [(f, None, (raw and getattr(self, f.attname) or f.pre_save(self, False))) for f in non_pks] 496 rows = manager.using(using).filter(pk=pk_val)._update(values) 497 if force_update and not rows: 498 raise DatabaseError("Forced update did not affect any rows.") 499 elif not (can_force_update or can_update): 506 500 if meta.order_with_respect_to: 507 501 # If this is a model with an order_with_respect_to 508 502 # autopopulate the _order field … … 519 513 values = [(f, f.get_db_prep_save(raw and getattr(self, f.attname) or f.pre_save(self, True), connection=connection)) 520 514 for f in meta.local_fields] 521 515 522 record_exists = False523 524 516 update_pk = bool(meta.has_auto_field and not pk_set) 525 517 if values: 526 518 # Create a new record. -
django/db/models/signals.py
diff -r 7fca770b5dc2 -r 0c51517ac4a0 django/db/models/signals.py
a b 5 5 pre_init = Signal(providing_args=["instance", "args", "kwargs"]) 6 6 post_init = Signal(providing_args=["instance"]) 7 7 8 pre_save = Signal(providing_args=["instance", "raw", " using"])8 pre_save = Signal(providing_args=["instance", "raw", "exists", "using"]) 9 9 post_save = Signal(providing_args=["instance", "raw", "created", "using"]) 10 10 11 11 pre_delete = Signal(providing_args=["instance", "using"]) -
tests/modeltests/signals/models.py
diff -r 7fca770b5dc2 -r 0c51517ac4a0 tests/modeltests/signals/models.py
a b 21 21 22 22 def pre_save_test(signal, sender, instance, **kwargs): 23 23 print 'pre_save signal,', instance 24 if 'exists' in kwargs: 25 if kwargs['exists']: 26 print 'Exists' 27 else: 28 print 'Does not exist' 24 29 if kwargs.get('raw'): 25 30 print 'Is raw' 26 31 … … 73 78 >>> p1 = Person(first_name='John', last_name='Smith') 74 79 >>> p1.save() 75 80 pre_save signal, John Smith 81 Does not exist 76 82 pre_save signal decorator, John Smith 77 83 post_save signal, John Smith 78 84 Is created … … 80 86 >>> p1.first_name = 'Tom' 81 87 >>> p1.save() 82 88 pre_save signal, Tom Smith 89 Exists 83 90 pre_save signal decorator, Tom Smith 84 91 post_save signal, Tom Smith 85 92 Is updated … … 88 95 >>> c1 = Car(make="Volkswagon", model="Passat") 89 96 >>> c1.save() 90 97 pre_save signal, Volkswagon Passat 98 Does not exist 91 99 pre_save signal decorator, Volkswagon Passat 92 100 pre_save signal decorator sender, Volkswagon Passat 93 101 post_save signal, Volkswagon Passat … … 96 104 # Calling an internal method purely so that we can trigger a "raw" save. 97 105 >>> p1.save_base(raw=True) 98 106 pre_save signal, Tom Smith 107 Exists 99 108 Is raw 100 109 pre_save signal decorator, Tom Smith 101 110 post_save signal, Tom Smith … … 112 121 >>> p2.id = 99999 113 122 >>> p2.save() 114 123 pre_save signal, James Jones 124 Does not exist 115 125 pre_save signal decorator, James Jones 116 126 post_save signal, James Jones 117 127 Is created … … 119 129 >>> p2.id = 99998 120 130 >>> p2.save() 121 131 pre_save signal, James Jones 132 Does not exist 122 133 pre_save signal decorator, James Jones 123 134 post_save signal, James Jones 124 135 Is created -
tests/regressiontests/signals_regress/tests.py
diff -r 7fca770b5dc2 -r 0c51517ac4a0 tests/regressiontests/signals_regress/tests.py
a b 9 9 10 10 def pre_save_test(signal, sender, instance, **kwargs): 11 11 signal_output.append('pre_save signal, %s' % instance) 12 if 'exists' in kwargs: 13 if kwargs['exists']: 14 signal_output.append('Exists') 15 else: 16 signal_output.append('Does not exist') 12 17 if kwargs.get('raw'): 13 18 signal_output.append('Is raw') 14 19 … … 74 79 a1 = Author(name='Neal Stephenson') 75 80 self.assertEquals(self.get_signal_output(a1.save), [ 76 81 "pre_save signal, Neal Stephenson", 82 "Does not exist", 77 83 "post_save signal, Neal Stephenson", 78 84 "Is created" 79 85 ]) 86 self.assertEquals(self.get_signal_output(a1.save), [ 87 "pre_save signal, Neal Stephenson", 88 "Exists", 89 "post_save signal, Neal Stephenson", 90 "Is updated" 91 ]) 80 92 81 93 b1 = Book(name='Snow Crash') 82 94 self.assertEquals(self.get_signal_output(b1.save), [ 83 95 "pre_save signal, Snow Crash", 96 "Does not exist", 84 97 "post_save signal, Snow Crash", 85 98 "Is created" 86 99 ]) 100 self.assertEquals(self.get_signal_output(b1.save), [ 101 "pre_save signal, Snow Crash", 102 "Exists", 103 "post_save signal, Snow Crash", 104 "Is updated" 105 ]) 87 106 88 107 def test_m2m_signals(self): 89 108 """ Assigning and removing to/from m2m shouldn't generate an m2m signal """