2

I want to group the model object according to the foreign key with a query or without any iteration.

example: Let, I have a model student:

class Student(models.Model):
    id=models.AutoField(primary_key=True)
    parentId=models.ForeignKey(parent)
    name=models.CharField()
    age=models.IntegerField()

Here I want to create the group the student object with respect to the parentId using a query or any optimized way.

GAJESH PANIGRAHI
  • 1,204
  • 10
  • 17

2 Answers2

2

Try using a defaultdict

    from collections import defaultdict

    students = defaultdict(list)
    for result in Student.objects.order_by('parentId'):
        students[result.parentId].append(result)
GAJESH PANIGRAHI
  • 1,204
  • 10
  • 17
zypro
  • 1,158
  • 3
  • 12
  • 33
1

If you order the elements by the foreign key, then you can use itertools.groupby for this:

from itertools import groupby
from operator import attrgetter

result = [
    list(v)
    for __, v in grouby(Student.objects.order('parentId_id'), attrgetter('parentId_id'))
]

or if you want to make a dictionary for where you map parent objects to a list of Students:

result = {
    k: list(v)
    for k, v in grouby(
        Student.objects.prefetch_realted('parentId').order('parentId_id'),
        attrgetter('parentId')
    )
}

This will thus generate a list of lists, where in each sublist, students with the same parentId are grouped together.

Note that ForeignKeys normally have no _id, or Id suffix. So you might want to change the model to:

class Student(models.Model):
    parent = models.ForeignKey()
    name = models.CharField()
    age = models.IntegerField()
Willem Van Onsem
  • 443,496
  • 30
  • 428
  • 555