Code

Ticket #214: get_values.patch

File get_values.patch, 3.0 KB (added by rmunn@…, 9 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