def save_base(self, raw=False, cls=None, origin=None, force_insert=False, force_update=False): """ Does the heavy-lifting involved in saving. Subclasses shouldn't need to override this method. It's separate from save() in order to hide the need for overrides of save() to pass around internal-only parameters ('raw', 'cls', and 'origin'). """ assert not (force_insert and force_update) if cls is None: cls = self.__class__ meta = cls._meta if not meta.proxy: origin = cls else: meta = cls._meta if origin: signals.pre_save.send(sender=origin, instance=self, raw=raw) # If we are in a raw save, save the object exactly as presented. # That means that we don't try to be smart about saving attributes # that might have come from the parent class - we just save the # attributes we have been given to the class we have been given. # We also go through this process to defer the save of proxy objects # to their actual underlying model. if not raw or meta.proxy: if meta.proxy: org = cls else: org = None for parent, field in meta.parents.items(): # At this point, parent's primary key field may be unknown # (for example, from administration form which doesn't fill # this field). If so, fill it. if field and getattr(self, parent._meta.pk.attname) is None and getattr(self, field.attname) is not None: setattr(self, parent._meta.pk.attname, getattr(self, field.attname)) self.save_base(cls=parent, origin=org) if field: setattr(self, field.attname, self._get_pk_val(parent._meta)) if meta.proxy: return if not meta.proxy: non_pks = [f for f in meta.local_fields if not f.primary_key] # First, try an UPDATE. If that doesn't update anything, do an INSERT. pk_val = self._get_pk_val(meta) pk_set = pk_val is not None record_exists = True manager = cls._base_manager if pk_set: # Determine whether a record with the primary key already exists. if (force_update or (not force_insert and manager.filter(pk=pk_val).exists())): # It does already exist, so do an UPDATE. if force_update or non_pks: values = [(f, None, (raw and getattr(self, f.attname) or f.pre_save(self, False))) for f in non_pks] rows = manager.filter(pk=pk_val)._update(values) if force_update and not rows: raise DatabaseError("Forced update did not affect any rows.") else: record_exists = False if not pk_set or not record_exists: if not pk_set: if force_update: raise ValueError("Cannot force an update in save() with no primary key.") values = [(f, f.get_db_prep_save(raw and getattr(self, f.attname) or f.pre_save(self, True))) for f in meta.local_fields if not isinstance(f, AutoField)] else: values = [(f, f.get_db_prep_save(raw and getattr(self, f.attname) or f.pre_save(self, True))) for f in meta.local_fields] if meta.order_with_respect_to: field = meta.order_with_respect_to values.append((meta.get_field_by_name('_order')[0], manager.filter(**{field.name: getattr(self, field.attname)}).count())) record_exists = False update_pk = bool(meta.has_auto_field and not pk_set) if values: # Create a new record. result = manager._insert(values, return_id=update_pk) else: # Create a new record with defaults for everything. result = manager._insert([(meta.pk, connection.ops.pk_default_value())], return_id=update_pk, raw_values=True) if update_pk: setattr(self, meta.pk.attname, result) transaction.commit_unless_managed() if origin: signals.post_save.send(sender=origin, instance=self, created=(not record_exists), raw=raw)
def save_base(self, raw=False, cls=None, force_insert=False, force_update=False): """ Does the heavy-lifting involved in saving. Subclasses shouldn't need to override this method. It's separate from save() in order to hide the need for overrides of save() to pass around internal-only parameters ('raw' and 'cls'). """ assert not (force_insert and force_update) if not cls: cls = self.__class__ meta = self._meta signal = True signals.pre_save.send(sender=self.__class__, instance=self, raw=raw) else: meta = cls._meta signal = False # If we are in a raw save, save the object exactly as presented. # That means that we don't try to be smart about saving attributes # that might have come from the parent class - we just save the # attributes we have been given to the class we have been given. if not raw: for parent, field in meta.parents.items(): # At this point, parent's primary key field may be unknown # (for example, from administration form which doesn't fill # this field). If so, fill it. if field and getattr( self, parent._meta.pk.attname) is None and getattr( self, field.attname) is not None: setattr(self, parent._meta.pk.attname, getattr(self, field.attname)) self.save_base(cls=parent) if field: setattr(self, field.attname, self._get_pk_val(parent._meta)) if meta.proxy: return if not meta.proxy: non_pks = [f for f in meta.local_fields if not f.primary_key] # First, try an UPDATE. If that doesn't update anything, do an INSERT. pk_val = self._get_pk_val(meta) pk_set = pk_val is not None record_exists = True manager = cls._base_manager if pk_set: # Determine whether a record with the primary key already exists. if (force_update or (not force_insert and manager.filter(pk=pk_val).extra(select={ 'a': 1 }).values('a').order_by())): # It does already exist, so do an UPDATE. if force_update or non_pks: values = [(f, None, (raw and getattr(self, f.attname) or f.pre_save(self, False))) for f in non_pks] rows = manager.filter(pk=pk_val)._update(values) if force_update and not rows: raise DatabaseError( "Forced update did not affect any rows.") else: record_exists = False if not pk_set or not record_exists: if not pk_set: if force_update: raise ValueError( "Cannot force an update in save() with no primary key." ) values = [ (f, f.get_db_prep_save(raw and getattr(self, f.attname) or f.pre_save(self, True))) for f in meta.local_fields if not isinstance(f, AutoField) ] else: values = [ (f, f.get_db_prep_save(raw and getattr(self, f.attname) or f.pre_save(self, True))) for f in meta.local_fields ] if meta.order_with_respect_to: field = meta.order_with_respect_to values.append( (meta.get_field_by_name('_order')[0], manager.filter( **{ field.name: getattr(self, field.attname) }).count())) record_exists = False update_pk = bool(meta.has_auto_field and not pk_set) if values: # Create a new record. result = manager._insert(values, return_id=update_pk) else: # Create a new record with defaults for everything. result = manager._insert( [(meta.pk, connection.ops.pk_default_value())], return_id=update_pk, raw_values=True) if update_pk: setattr(self, meta.pk.attname, result) transaction.commit_unless_managed() if signal: signals.post_save.send(sender=self.__class__, instance=self, created=(not record_exists), raw=raw)
def save_base(self, raw=False, cls=None): """ Does the heavy-lifting involved in saving. Subclasses shouldn't need to override this method. It's separate from save() in order to hide the need for overrides of save() to pass around internal-only parameters ('raw' and 'cls'). """ if not cls: cls = self.__class__ meta = self._meta signal = True dispatcher.send(signal=signals.pre_save, sender=self.__class__, instance=self, raw=raw) else: meta = cls._meta signal = False # If we are in a raw save, save the object exactly as presented. # That means that we don't try to be smart about saving attributes # that might have come from the parent class - we just save the # attributes we have been given to the class we have been given. if not raw: for parent, field in meta.parents.items(): self.save_base(raw, parent) setattr(self, field.attname, self._get_pk_val(parent._meta)) non_pks = [f for f in meta.local_fields if not f.primary_key] # First, try an UPDATE. If that doesn't update anything, do an INSERT. pk_val = self._get_pk_val(meta) # Note: the comparison with '' is required for compatibility with # oldforms-style model creation. pk_set = pk_val is not None and smart_unicode(pk_val) != u'' record_exists = True manager = cls._default_manager if pk_set: # Determine whether a record with the primary key already exists. if manager.filter(pk=pk_val).extra(select={ 'a': 1 }).values('a').order_by(): # It does already exist, so do an UPDATE. if non_pks: values = [ (f, None, f.get_db_prep_save(raw and getattr(self, f.attname) or f.pre_save(self, False))) for f in non_pks ] manager.filter(pk=pk_val)._update(values) else: record_exists = False if not pk_set or not record_exists: if not pk_set: values = [(f, f.get_db_prep_save(raw and getattr(self, f.attname) or f.pre_save(self, True))) for f in meta.local_fields if not isinstance(f, AutoField)] else: values = [(f, f.get_db_prep_save(raw and getattr(self, f.attname) or f.pre_save(self, True))) for f in meta.local_fields] if meta.order_with_respect_to: field = meta.order_with_respect_to values.append( (meta.get_field_by_name('_order')[0], manager.filter(**{ field.name: getattr(self, field.attname) }).count())) record_exists = False update_pk = bool(meta.has_auto_field and not pk_set) if values: # Create a new record. result = manager._insert(values, return_id=update_pk) else: # Create a new record with defaults for everything. result = manager._insert( [(meta.pk, connection.ops.pk_default_value())], return_id=update_pk, raw_values=True) if update_pk: setattr(self, meta.pk.attname, result) transaction.commit_unless_managed() if signal: dispatcher.send(signal=signals.post_save, sender=self.__class__, instance=self, created=(not record_exists), raw=raw)
def save_base(self, raw=False, cls=None): """ Does the heavy-lifting involved in saving. Subclasses shouldn't need to override this method. It's separate from save() in order to hide the need for overrides of save() to pass around internal-only parameters ('raw' and 'cls'). """ if not cls: cls = self.__class__ meta = self._meta signal = True dispatcher.send(signal=signals.pre_save, sender=self.__class__, instance=self, raw=raw) else: meta = cls._meta signal = False # If we are in a raw save, save the object exactly as presented. # That means that we don't try to be smart about saving attributes # that might have come from the parent class - we just save the # attributes we have been given to the class we have been given. if not raw: for parent, field in list(meta.parents.items()): # At this point, parent's primary key field may be unknown # (for example, from administration form which doesn't fill # this field). If so, fill it. if getattr(self, parent._meta.pk.attname) is None and getattr(self, field.attname) is not None: setattr(self, parent._meta.pk.attname, getattr(self, field.attname)) self.save_base(raw, parent) setattr(self, field.attname, self._get_pk_val(parent._meta)) non_pks = [f for f in meta.local_fields if not f.primary_key] # First, try an UPDATE. If that doesn't update anything, do an INSERT. pk_val = self._get_pk_val(meta) # Note: the comparison with '' is required for compatibility with # oldforms-style model creation. pk_set = pk_val is not None and smart_unicode(pk_val) != '' record_exists = True manager = cls._default_manager if pk_set: # Determine whether a record with the primary key already exists. if manager.filter(pk=pk_val).extra(select={'a': 1}).values('a').order_by(): # It does already exist, so do an UPDATE. if non_pks: values = [(f, None, f.get_db_prep_save(raw and getattr(self, f.attname) or f.pre_save(self, False))) for f in non_pks] manager.filter(pk=pk_val)._update(values) else: record_exists = False if not pk_set or not record_exists: if not pk_set: values = [(f, f.get_db_prep_save(raw and getattr(self, f.attname) or f.pre_save(self, True))) for f in meta.local_fields if not isinstance(f, AutoField)] else: values = [(f, f.get_db_prep_save(raw and getattr(self, f.attname) or f.pre_save(self, True))) for f in meta.local_fields] if meta.order_with_respect_to: field = meta.order_with_respect_to values.append((meta.get_field_by_name('_order')[0], manager.filter(**{field.name: getattr(self, field.attname)}).count())) record_exists = False update_pk = bool(meta.has_auto_field and not pk_set) if values: # Create a new record. result = manager._insert(values, return_id=update_pk) else: # Create a new record with defaults for everything. result = manager._insert([(meta.pk, connection.ops.pk_default_value())], return_id=update_pk, raw_values=True) if update_pk: setattr(self, meta.pk.attname, result) transaction.commit_unless_managed() if signal: dispatcher.send(signal=signals.post_save, sender=self.__class__, instance=self, created=(not record_exists), raw=raw)
def save_base(self, raw=False, cls=None, force_insert=False, force_update=False): """ Does the heavy-lifting involved in saving. Subclasses shouldn't need to override this method. It's separate from save() in order to hide the need for overrides of save() to pass around internal-only parameters ('raw' and 'cls'). """ assert not (force_insert and force_update) if not cls: cls = self.__class__ meta = self._meta signal = True signals.pre_save.send(sender=self.__class__, instance=self, raw=raw) else: meta = cls._meta signal = False # If we are in a raw save, save the object exactly as presented. # That means that we don't try to be smart about saving attributes # that might have come from the parent class - we just save the # attributes we have been given to the class we have been given. if not raw: # TODO: GAHHHHHHH for parent, field in meta.parents.items(): # At this point, parent's primary key field may be unknown # (for example, from administration form which doesn't fill # this field). If so, fill it. # TODO: test that this is good enough if getattr(self, parent._meta.pks[0].attname) is None and getattr(self, field.attname) is None: # if getattr(self, parent._meta.pk.attname) is None and getattr(self, field.attname) is not None: for f in parent._meta.pks: setattr(self, f.attname, getattr(self, field.attname)) # setattr(self, parent._meta.pk.attname, getattr(self, field.attname)) self.save_base(raw, parent) setattr(self, field.attname, self._get_pk_val(parent._meta)) non_pks = [f for f in meta.local_fields if not f.primary_key] # First, try an UPDATE. If that doesn't update anything, do an INSERT. pk_val = self._get_pk_val(meta) pk_set = bool(pk_val) if pk_val: if not hasattr(pk_val, "__iter__"): pk_val = [pk_val] for pk in pk_val: if not pk: pk_set = False break record_exists = True manager = cls._default_manager if pk_set: # Determine whether a record with the primary key already exists. if force_update or ( not force_insert and manager.filter(pk=pk_val).extra(select={"a": 1}).values("a").order_by() ): # It does already exist, so do an UPDATE. if force_update or non_pks: values = [ (f, None, f.get_db_prep_save(raw and getattr(self, f.attname) or f.pre_save(self, False))) for f in non_pks ] rows = manager.filter(pk=pk_val)._update(values) if force_update and not rows: raise DatabaseError("Forced update did not affect any rows.") else: record_exists = False if not pk_set or not record_exists: if not pk_set: if force_update: raise ValueError("Cannot force an update in save() with no primary key.") values = [ (f, f.get_db_prep_save(raw and getattr(self, f.attname) or f.pre_save(self, True))) for f in meta.local_fields if not isinstance(f, AutoField) ] else: values = [ (f, f.get_db_prep_save(raw and getattr(self, f.attname) or f.pre_save(self, True))) for f in meta.local_fields ] if meta.order_with_respect_to: field = meta.order_with_respect_to values.append( ( meta.get_field_by_name("_order")[0], manager.filter(**{field.name: getattr(self, field.attname)}).count(), ) ) record_exists = False update_pk = bool(meta.has_auto_field and not pk_set) if values: # Create a new record. result = manager._insert(values, return_id=update_pk) else: # Create a new record with defaults for everything. result = manager._insert( [(meta.pk, connection.ops.pk_default_value())], return_id=update_pk, raw_values=True ) if update_pk: # Find the AutoField # TODO: this code is repeated in subqueries.py -- needs changed attname = meta.pks[0].attname for pk in meta.pks: if isinstance(pk, AutoField): attname = pk.attname setattr(self, attname, result) transaction.commit_unless_managed() if signal: signals.post_save.send(sender=self.__class__, instance=self, created=(not record_exists), raw=raw)