Skip to content

Commit caa7150

Browse files
authored
Merge pull request #151 from sundyloveme/master
Support read_frame for paging
2 parents 026e93d + 3051374 commit caa7150

File tree

2 files changed

+47
-7
lines changed

2 files changed

+47
-7
lines changed

django_pandas/io.py

+35-7
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
1-
import pandas as pd
2-
from .utils import update_with_verbose, get_related_model
31
import django
2+
import pandas as pd
43

4+
from .utils import update_with_verbose, get_related_model
55

66
FieldDoesNotExist = (
77
django.db.models.fields.FieldDoesNotExist
@@ -36,7 +36,10 @@ def is_values_queryset(qs):
3636
if django.VERSION < (1, 9): # pragma: no cover
3737
return isinstance(qs, django.db.models.query.ValuesQuerySet)
3838
else:
39-
return qs._iterable_class == django.db.models.query.ValuesIterable
39+
try:
40+
return qs._iterable_class == django.db.models.query.ValuesIterable
41+
except:
42+
return False
4043

4144

4245
def read_frame(qs, fieldnames=(), index_col=None, coerce_float=False,
@@ -117,14 +120,23 @@ def read_frame(qs, fieldnames=(), index_col=None, coerce_float=False,
117120
*(f for f in zip(fieldnames, fields)
118121
if f[0] not in uniq_fields and not uniq_fields.add(f[0])))
119122
else:
120-
fields = qs.model._meta.fields
121-
fieldnames = [f.name for f in fields]
122-
fieldnames += list(qs.query.annotation_select.keys())
123+
try:
124+
fields = qs.model._meta.fields
125+
fieldnames = [f.name for f in fields]
126+
fieldnames += list(qs.query.annotation_select.keys())
127+
except:
128+
pass
123129

124130
if is_values_queryset(qs):
125131
recs = list(qs)
126132
else:
127-
recs = list(qs.values_list(*fieldnames))
133+
try:
134+
recs = list(qs.values_list(*fieldnames))
135+
except:
136+
if fieldnames:
137+
recs = [object_to_dict(q, fieldnames) for q in qs]
138+
else:
139+
recs = [object_to_dict(q) for q in qs]
128140

129141
df = pd.DataFrame.from_records(
130142
recs,
@@ -141,3 +153,19 @@ def read_frame(qs, fieldnames=(), index_col=None, coerce_float=False,
141153
if datetime_index:
142154
df.index = pd.to_datetime(df.index, errors="ignore")
143155
return df
156+
157+
158+
def object_to_dict(obj, fields: list = None):
159+
"""
160+
Convert obj to a dictionary
161+
162+
Parameters
163+
----------
164+
165+
obj: obj to an item of QuerySet
166+
fieldnames: reserved fields, default to all fields
167+
"""
168+
if not fields:
169+
obj.__dict__.pop('_state')
170+
return obj.__dict__
171+
return {field: obj.__dict__.get(field) for field in fields}

django_pandas/tests/test_io.py

+12
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
from django.core.paginator import Paginator
12
from django.test import TestCase
23
import django
34
from django.db.models import Sum
@@ -47,6 +48,17 @@ def test_basic(self):
4748
df1 = read_frame(qs, ['col1', 'col2'])
4849
self.assertEqual(df1.shape, (qs.count(), 2))
4950

51+
def test_page(self):
52+
qs = MyModel.objects.all()
53+
qs_list: list = Paginator(qs, 3).page(1).object_list
54+
df = read_frame(qs_list, verbose=False)
55+
self.assertEqual(list(df.columns),
56+
['id', 'index_col', 'col1', 'col2', 'col3', 'col4'])
57+
58+
df = read_frame(qs_list, verbose=False, fieldnames=['col1', 'col2'])
59+
self.assertEqual(list(df.columns),
60+
['col1', 'col2'])
61+
5062
def test_values(self):
5163
qs = MyModel.objects.all()
5264
qs = qs.extra(select={"ecol1": "col1+1"})

0 commit comments

Comments
 (0)