Пример #1
0
    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)
Пример #2
0
    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)
Пример #3
0
    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)
Пример #4
0
    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)
Пример #5
0
    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)