0

I have the following model for a Measurement belonging to a user:

class Measurement(models.Model):
    user = models.ForeignKey(User, related_name='measurements')
    timestamp = models.DateTimeField(default=timezone.now, db_index=True)

    def get_date(self):
        return self.timestamp.date()

And for one of my views I need the measurements grouped by day. I have done the following:

def group_measurements_by_days(user_id):
    measurements = Measurement.objects.filter(user=user_id)
    daysd = {}
    for measurement in measurements:
        day = measurement.get_date()
        if not day in daysd:
            daysd[day] = []
        mymeas = daysd[day]
        mymeas.append(measurement)
    days = [{'day': day, 'measurements': measurements} for day, measurements in daysd.items()]
    days = sorted(days, key=itemgetter('day'), reverse=True)
    return days

So that I get a list like:

[
  { 'day': date1, 'measurements': [ Measurement, Measurement, ...]},
  { 'day': date2, 'measurements': [ Measurement, Measurement, ...]},  
  ...
]

But this is completely wrong, because I have a mixture of plain python types and django ORM types. This works when I use this data in templates, but is giving me trouble in other areas.

For example, when trying to reuse this code for a django rest api, I suddenly am unable to serialize those objects.

How can I process the data coming from the django ORM (Measurement.objects.filter(user=user_id)), but still keep a consistent format for my API?

blueFast
  • 41,341
  • 63
  • 198
  • 344
  • If you need this to show it in a template, you could use [regroup](https://docs.djangoproject.com/en/1.8/ref/templates/builtins/#regroup) built-in template tag from Django. – Gocht Oct 13 '15 at 19:02
  • Why don't you wrap your for loop into a util function, then have an additional parameter to control the return value to be either your current data structure or plain python string that is serializable? Also you could make `daysd` a `defaultdict(list)` instead of `{}`, then you don't need those `if` statement anymore. – Shang Wang Oct 13 '15 at 19:16
  • By the way, you can replace your `if` statement with something like this ... `daysd.setdefault(day, []).append(measurement)` – jcfollower Oct 13 '15 at 19:29

2 Answers2

0

Hopefully, you are able to use Django 1.8. Problem solved in this post credits goes there.

You can filter the queryset using grouping by date:

from django.db.models.expressions import Date

queryset = Measurements.objects.filter(user=user_id).annotate(day=Date('timestamp'), measurements=Count(0)).values('day', 'measurements')
Community
  • 1
  • 1
Roba
  • 646
  • 4
  • 13
0

How about using this idea ...

    mymeas.append(measurement.__dict__)
Community
  • 1
  • 1
jcfollower
  • 3,103
  • 19
  • 25