martsberger / django-pivot

A module for pivoting Django Querysets
MIT License
209 stars 16 forks source link

row_range not working #24

Closed GarikFirst closed 2 years ago

GarikFirst commented 2 years ago

I’m trying to pivot my data:

trackings = pivot(trackings, 'project', 'date', ‘time’)
for record in trackings:
    print(record)

Result:

{'project': 1, '2022-03-28': datetime.timedelta(seconds=14400), '2022-03-29': None, '2022-03-30': None}
{'project': 2, '2022-03-28': datetime.timedelta(seconds=90), '2022-03-29': None, '2022-03-30': datetime.timedelta(seconds=3900)}
{'project': 3, '2022-03-28': None, '2022-03-29': datetime.timedelta(seconds=21600), '2022-03-30': None}

Now with row_range:

row_range = [date(2022, 3, 28) + timedelta(days) for days in range(8)]
trackings = pivot(trackings, 'project', 'date', 'time', row_range=row_range)

for record in trackings:
    print(record)

Result:

{'project': datetime.date(2022, 3, 28), datetime.date(2022, 3, 28): None, datetime.date(2022, 3, 29): None, datetime.date(2022, 3, 30): None}
{'project': datetime.date(2022, 3, 29), datetime.date(2022, 3, 28): None, datetime.date(2022, 3, 29): None, datetime.date(2022, 3, 30): None}
{'project': datetime.date(2022, 3, 30), datetime.date(2022, 3, 28): None, datetime.date(2022, 3, 29): None, datetime.date(2022, 3, 30): None}
{'project': datetime.date(2022, 3, 31), datetime.date(2022, 3, 28): None, datetime.date(2022, 3, 29): None, datetime.date(2022, 3, 30): None}
{'project': datetime.date(2022, 4, 1), datetime.date(2022, 3, 28): None, datetime.date(2022, 3, 29): None, datetime.date(2022, 3, 30): None}
{'project': datetime.date(2022, 4, 2), datetime.date(2022, 3, 28): None, datetime.date(2022, 3, 29): None, datetime.date(2022, 3, 30): None}
{'project': datetime.date(2022, 4, 3), datetime.date(2022, 3, 28): None, datetime.date(2022, 3, 29): None, datetime.date(2022, 3, 30): None}
{'project': datetime.date(2022, 4, 4), datetime.date(2022, 3, 28): None, datetime.date(2022, 3, 29): None, datetime.date(2022, 3, 30): None}

What am I doing wrong? Seems row_range is not working

martsberger commented 2 years ago

It looks like maybe the documentation in the Readme is wrong. The first parameter to pivot is the row and the second parameter is the column. In order to fill in the date using row_range you'd want

row_range = [date(2022, 3, 28) + timedelta(days) for days in range(8)]
trackings = pivot(trackings, 'date', 'project', 'time', row_range=row_range)
GarikFirst commented 2 years ago

Thank you for your very quick response!

Oh, I got the point - if I want to populate dates by row_range - date should always be first parameter (which is row).

I ended up with something like this

dates = [datetime.date(2022, 3, 28), datetime.date(2022, 3, 29), datetime.date(2022, 3, 30), datetime.date(
    2022, 3, 31), datetime.date(2022, 4, 1), datetime.date(2022, 4, 2), datetime.date(2022, 4, 3)]

tracks = [{'project': 1, '2022-03-28': datetime.timedelta(seconds=14400), '2022-03-29': None, '2022-03-30': None},
{'project': 2, '2022-03-28': datetime.timedelta(seconds=90), '2022-03-29': None, '2022-03-30': datetime.timedelta(seconds=3900)},
{'project': 3, '2022-03-28': None, '2022-03-29': datetime.timedelta(seconds=21600), '2022-03-30': None}]

for t in tracks:
    for d in dates:
        if str(d) not in t:
            t[str(d)] = None

And get list of dicts as I wanted (to easy iterate in Django template later):

[{'project': 1, '2022-03-28': datetime.timedelta(seconds=14400), '2022-03-29': None, '2022-03-30': None, '2022-03-31': None, '2022-04-01': None, '2022-04-02': None, '2022-04-03': None}, {'project': 2, '2022-03-28': datetime.timedelta(seconds=90), '2022-03-29': None, '2022-03-30': datetime.timedelta(seconds=3900), '2022-03-31': None, '2022-04-01': None, '2022-04-02': None, '2022-04-03': None}, {'project': 3, '2022-03-28': None, '2022-03-29': datetime.timedelta(seconds=21600), '2022-03-30': None, '2022-03-31': None, '2022-04-01': None, '2022-04-02': None, '2022-04-03': None}]
GarikFirst commented 2 years ago

As designed