Ticket #214: get_values.patch

File get_values.patch, 3.0 KB (added by rmunn@…, 10 years ago)

Patch to add get_values() and get_values_iterator()

  • django/core/meta.py

     
    562562        new_mod.get_iterator = curry(function_get_iterator, opts, new_class)
    563563        new_mod.get_iterator.__doc__ = "Returns an iterator of %s objects matching the given parameters." % name
    564564
     565        new_mod.get_values = curry(function_get_values_list, opts, new_class)
     566        new_mod.get_values.__doc__ = "Returns a list of dicts matching the given parameters."
     567
     568        new_mod.get_values_iterator = curry(function_get_values_iterator, opts, new_class)
     569        new_mod.get_values_iterator.__doc__ = "Returns an iterator of dicts matching the given parameters."
     570
    565571        new_mod.get_count = curry(function_get_count, opts)
    566572        new_mod.get_count.__doc__ = "Returns the number of %s objects matching the given parameters." % name
    567573
     
    10471053            setattr(obj, f.rel.get_cache_name(), rel_obj)
    10481054    return obj, index_end
    10491055
     1056def function_get_values_iterator(opts, klass, **kwargs):
     1057    """
     1058    Return SELECT results as a list of dicts rather than as objects.
     1059    Example use: "SELECT DISTINCT year, month FROM blog ORDER BY year, month"
     1060    """
     1061    # kwargs['select'] is a dictionary, and dictionaries' key order is
     1062    # undefined, so we convert it to a list of tuples internally.
     1063    kwargs['select'] = kwargs.get('select', {}).items()
     1064
     1065    cursor = db.db.cursor()
     1066    _, sql, params = function_get_sql_clause(opts, **kwargs)
     1067    # Allow user to specify a specific list of fields to fetch
     1068    fields = kwargs.get('fields')
     1069    if isinstance(fields, basestring):
     1070        # Be forgiving of mistakes: convert to tuple
     1071        fields = (fields,)
     1072    if not fields:
     1073        # Default to all fields
     1074        fields = [f.name for f in opts.fields]
     1075    select = ['%s.%s' % (opts.db_table, f) for f in fields]
     1076    cursor.execute("SELECT " + (kwargs.get('distinct') and "DISTINCT " or "") + ",".join(select) + sql, params)
     1077    while 1:
     1078        rows = cursor.fetchmany(GET_ITERATOR_CHUNK_SIZE)
     1079        if not rows:
     1080            raise StopIteration
     1081        for row in rows:
     1082            yield dict(zip(fields, row))
     1083
     1084def function_get_values_list(opts, klass, **kwargs):
     1085    return list(function_get_values_iterator(opts, klass, **kwargs))
     1086
    10501087def function_get_iterator(opts, klass, **kwargs):
    10511088    # kwargs['select'] is a dictionary, and dictionaries' key order is
    10521089    # undefined, so we convert it to a list of tuples internally.
     
    11171154    # table_count is used to ensure table aliases are unique.
    11181155    tables, join_where, where, params = [], [], [], []
    11191156    for kwarg, kwarg_value in kwarg_items:
    1120         if kwarg in ('order_by', 'limit', 'offset', 'select_related', 'distinct', 'select', 'tables', 'where', 'params'):
     1157        if kwarg in ('order_by', 'limit', 'offset', 'select_related', 'distinct', 'select', 'tables', 'where', 'params', 'fields'):
    11211158            continue
    11221159        if kwarg_value is None:
    11231160            continue
Back to Top