471 | | Does the heavy-lifting involved in saving. Subclasses shouldn't need to |
472 | | override this method. It's separate from save() in order to hide the |
473 | | need for overrides of save() to pass around internal-only parameters |
474 | | ('raw', 'cls', and 'origin'). |
| 470 | This method does some setup unique to the first save (signals, |
| 471 | transaction handling etc). |
| 472 | |
| 473 | The actual saving is delegated to _save_base. |
478 | | if cls is None: |
479 | | cls = self.__class__ |
480 | | meta = cls._meta |
481 | | if not meta.proxy: |
482 | | origin = cls |
483 | | else: |
484 | | meta = cls._meta |
| 476 | cls = self.__class__ |
| 477 | using = using or router.db_for_write(cls, instance=self) |
| 478 | if not cls._meta.auto_created: |
| 479 | signals.pre_save.send(sender=cls, instance=self, raw=raw, using=using) |
| 480 | |
| 481 | record_exists = self._save_base(raw, cls, force_insert, force_update, using) |
| 482 | # Store the database on which the object was saved |
| 483 | self._state.db = using |
| 484 | # Once saved, this is no longer a to-be-added instance. |
| 485 | self._state.adding = False |
486 | | if origin and not meta.auto_created: |
487 | | signals.pre_save.send(sender=origin, instance=self, raw=raw, using=using) |
| 487 | # Commit the transaction & signal that the save is complete. |
| 488 | transaction.commit_unless_managed(using=using) |
| 489 | if not cls._meta.auto_created: |
| 490 | signals.post_save.send(sender=cls, instance=self, |
| 491 | created=(not record_exists), raw=raw, using=using) |
| 492 | |
| 493 | save_base.alters_data = True |
| 494 | |
| 495 | def _save_base(self, raw, cls, force_insert, force_update, using): |
| 496 | """ |
| 497 | Does the heavy-lifting involved in saving. Subclasses shouldn't need to |
| 498 | override this method. |
| 499 | |
| 500 | Internal parameters: |
| 501 | - raw: If set, save just the table used by self.__class__. That is, do |
| 502 | not follow inheritance chains, except for proxy-skipping. |
| 503 | - cls: The class we are currently saving. self.__class__ or one of its |
| 504 | parents. |
| 505 | """ |
| 506 | meta = cls._meta |
| 507 | # Skip proxy chains. Defer the save of proxy objects to their actual |
| 508 | # underlying model. |
| 509 | if meta.proxy: |
| 510 | # A proxy model can have only one parent. |
| 511 | parent, field = meta.parents.items()[0] |
| 512 | return self._save_base(raw, parent, force_insert, force_update, using) |
511 | | if meta.proxy: |
512 | | return |
513 | | |
514 | | if not meta.proxy: |
515 | | non_pks = [f for f in meta.local_fields if not f.primary_key] |
516 | | |
517 | | # First, try an UPDATE. If that doesn't update anything, do an INSERT. |
518 | | pk_val = self._get_pk_val(meta) |
519 | | pk_set = pk_val is not None |
520 | | record_exists = True |
521 | | manager = cls._base_manager |
522 | | if pk_set: |
523 | | # Determine whether a record with the primary key already exists. |
524 | | if (force_update or (not force_insert and |
525 | | manager.using(using).filter(pk=pk_val).exists())): |
526 | | # It does already exist, so do an UPDATE. |
527 | | if force_update or non_pks: |
528 | | values = [(f, None, (raw and getattr(self, f.attname) or f.pre_save(self, False))) for f in non_pks] |
529 | | if values: |
530 | | rows = manager.using(using).filter(pk=pk_val)._update(values) |
531 | | if force_update and not rows: |
532 | | raise DatabaseError("Forced update did not affect any rows.") |
533 | | else: |
534 | | record_exists = False |
535 | | if not pk_set or not record_exists: |
536 | | if meta.order_with_respect_to: |
537 | | # If this is a model with an order_with_respect_to |
538 | | # autopopulate the _order field |
539 | | field = meta.order_with_respect_to |
540 | | order_value = manager.using(using).filter(**{field.name: getattr(self, field.attname)}).count() |
541 | | self._order = order_value |
542 | | |
543 | | fields = meta.local_fields |
544 | | if not pk_set: |
545 | | if force_update: |
546 | | raise ValueError("Cannot force an update in save() with no primary key.") |
547 | | fields = [f for f in fields if not isinstance(f, AutoField)] |
| 534 | non_pks = [f for f in meta.local_fields if not f.primary_key] |
| 535 | |
| 536 | pk_val = self._get_pk_val(meta) |
| 537 | pk_set = pk_val is not None |
| 538 | record_exists = True |
| 539 | manager = cls._base_manager |
| 540 | if pk_set: |
| 541 | # Determine whether a record with the primary key already exists. |
| 542 | if (force_update or (not force_insert and |
| 543 | manager.using(using).filter(pk=pk_val).exists())): |
| 544 | # It does already exist, so do an UPDATE. |
| 545 | if force_update or non_pks: |
| 546 | values = [(f, None, (raw and getattr(self, f.attname) or f.pre_save(self, False))) for f in non_pks] |
| 547 | if values: |
| 548 | rows = manager.using(using).filter(pk=pk_val)._update(values) |
| 549 | if force_update and not rows: |
| 550 | raise DatabaseError("Forced update did not affect any rows.") |
| 551 | else: |
550 | | |
551 | | update_pk = bool(meta.has_auto_field and not pk_set) |
552 | | result = manager._insert([self], fields=fields, return_id=update_pk, using=using, raw=raw) |
553 | | |
554 | | if update_pk: |
555 | | setattr(self, meta.pk.attname, result) |
556 | | transaction.commit_unless_managed(using=using) |
557 | | |
558 | | # Store the database on which the object was saved |
559 | | self._state.db = using |
560 | | # Once saved, this is no longer a to-be-added instance. |
561 | | self._state.adding = False |
562 | | |
563 | | # Signal that the save is complete |
564 | | if origin and not meta.auto_created: |
565 | | signals.post_save.send(sender=origin, instance=self, |
566 | | created=(not record_exists), raw=raw, using=using) |
567 | | |
568 | | |
569 | | save_base.alters_data = True |
| 553 | if not pk_set or not record_exists: |
| 554 | if meta.order_with_respect_to: |
| 555 | # If this is a model with an order_with_respect_to |
| 556 | # autopopulate the _order field |
| 557 | field = meta.order_with_respect_to |
| 558 | order_value = manager.using(using).filter(**{field.name: getattr(self, field.attname)}).count() |
| 559 | self._order = order_value |
| 560 | |
| 561 | fields = meta.local_fields |
| 562 | if not pk_set: |
| 563 | if force_update: |
| 564 | raise ValueError("Cannot force an update in save() with no primary key.") |
| 565 | fields = [f for f in fields if not isinstance(f, AutoField)] |
| 566 | |
| 567 | record_exists = False |
| 568 | |
| 569 | update_pk = bool(meta.has_auto_field and not pk_set) |
| 570 | result = manager._insert([self], fields=fields, return_id=update_pk, using=using, raw=raw) |
| 571 | |
| 572 | if update_pk: |
| 573 | setattr(self, meta.pk.attname, result) |
| 574 | return record_exists |
| 575 | |
| 576 | _save_base.alters_data = True |