Beispiel #1
0
    def _insert(self, objs, fields, **kwargs):
        """
        Replaces standard insert procedure for bulk_create_returning
        """
        if not getattr(self.model, '_insert_returning', False):
            return QuerySet._insert(self, objs, fields, **kwargs)

        # Returns attname, not column.
        # Before django 1.10 pk fields hasn't been returned from postgres.
        # In this case, I can't match bulk_create results and return values by primary key.
        # So I select all data from returned results
        return_fields = self._get_fields(
            ignore_deferred=(django.VERSION < (1, 10)))
        assert len(return_fields) == 1 and list(return_fields.keys())[0] == self.model, \
            "You can't fetch relative model fields with returning operation"

        self._for_write = True
        using = kwargs.get('using', None) or self.db

        query_kwargs = {} if django.VERSION < (2, 2) else {
            'ignore_conflicts': kwargs.get('ignore_conflicts')
        }
        query = sql.InsertQuery(self.model, **query_kwargs)
        query.insert_values(fields, objs, raw=kwargs.get('raw'))

        self.model._insert_returning_cache = self._execute_sql(query,
                                                               return_fields,
                                                               using=using)
        if django.VERSION < (3, ):
            if not kwargs.get('return_id', False):
                return None

            inserted_ids = self.model._insert_returning_cache.values_list(
                self.model._meta.pk.column, flat=True)
            if not inserted_ids:
                return None

            return list(
                inserted_ids) if len(inserted_ids) > 1 else inserted_ids[0]
        else:
            returning_fields = kwargs.get('returning_fields', None)
            if returning_fields is None:
                return None

            columns = [f.column for f in returning_fields]

            # In django 3.0 single result is returned if single object is returned...
            flat = django.VERSION < (3, 1) and len(objs) <= 1

            return self.model._insert_returning_cache.values_list(*columns,
                                                                  flat=flat)