def get_connection(self): from django.db import get_current_connection return self.connection or get_current_connection()
def save_base(self, raw=False, cls=None, force_insert=False, force_update=False, using=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'). """ 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 # get model's connection from django.db import get_current_connection, get_connection if using: conn = get_connection(using) else: if hasattr(self,'__connection__'): conn = self.__connection__ elif meta.using: conn = get_connection(meta.using) else: conn = get_current_connection() # 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 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) pk_set = pk_val is not None 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.get_query_set_by_connection(conn).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), conn)) for f in non_pks] rows = manager.get_query_set_by_connection(conn).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), conn)) 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), conn)) 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, connection=conn) else: # Create a new record with defaults for everything. result = manager._insert([(meta.pk, conn.ops.pk_default_value())], return_id=update_pk, raw_values=True, connection=conn) if update_pk: setattr(self, meta.pk.attname, result) transaction.commit_unless_managed(conn) # need by connection if signal: signals.post_save.send(sender=self.__class__, instance=self, created=(not record_exists), raw=raw)