Return an iterator over the model instances (or queryset) that yeilds lists of values

    This forms a table suitable for output as a csv

    FIXME: allow specification of related field values with double_underscore

    >>> from django.contrib.auth.models import Permission
    >>> from django.db.models.base import ModelState
    >>> t = table_generator_from_list_of_instances(list(Permission.objects.all()))
    >>> import types
    >>> isinstance(t, types.GeneratorType)
    True
    >>> t = list(t)
    >>> len(t) > 3
    True
    >>> len(t[0])
    5
    >>> isinstance(t[0][0], basestring)
    True
    >>> isinstance(t[0][-1], basestring)
    True
    >>> isinstance(t[1][0], int)
    True
    >>> isinstance(t[0][2], basestring)
    True
    >>> isinstance(t[1][2], ModelState)
    True
    >>> isinstance(t[-1][2], ModelState)
    True

def table_generator_from_list_of_instances(data, field_names=None, excluded_field_names=None, sort=True, excel_dialect=True, eval_python=False):
    '''Return an iterator over the model instances (or queryset) that yeilds lists of values

    This forms a table suitable for output as a csv

    FIXME: allow specification of related field values with double_underscore

    >>> from django.contrib.auth.models import Permission
    >>> from django.db.models.base import ModelState
    >>> t = table_generator_from_list_of_instances(list(Permission.objects.all()))
    >>> import types
    >>> isinstance(t, types.GeneratorType)
    True
    >>> t = list(t)
    >>> len(t) > 3
    True
    >>> len(t[0])
    5
    >>> isinstance(t[0][0], basestring)
    True
    >>> isinstance(t[0][-1], basestring)
    True
    >>> isinstance(t[1][0], int)
    True
    >>> isinstance(t[0][2], basestring)
    True
    >>> isinstance(t[1][2], ModelState)
    True
    >>> isinstance(t[-1][2], ModelState)
    True
    '''
    excluded_field_names = excluded_field_names or []
    excluded_field_names += '_state'
    excluded_field_names = set(excluded_field_names)

    for i, row in enumerate(data):
        if not field_names or not any(field_names):
            field_names = [k for (k, v) in row.__dict__.iteritems() if not k in excluded_field_names]
        if not i:
            yield field_names
        yield [follow_double_underscores(row, field_name=k, excel_dialect=True, eval_python=eval_python) for k in field_names]