Как эффективно использовать _set.all() в Django?

Есть ли способ в django сделать следующее более эффективно, когда число объектов Entry превышает 5000 записей?

models.py

class Entry(models.Model):
    user = models.TextField(db_column='User', blank=True)
    date = models.DateTimeField(blank=True)

class Color(models.Model):
    color = models.TextField(blank=True)
    entry = models.ForeignKey(Entry)

И скажем, я хотел получить все цвета для каждой из этих записей...

entrys = Entry.objects.all()

for e in entrys:
    print e.color_set.all()

Я хочу иметь возможность связать каждый объект с определенной записью. Например, в таблице CSV, как это.

user, color
john, blue
john, orange
bob, green
bob, red
bob, purple

Требуется несколько секунд, чтобы просмотреть все мои записи. Есть ли способ лучше?

2 ответа

Решение

Вы должны использовать prefetch_related

entrys = Entry.objects.all().prefetch_related('color_set')

for e in entrys:
    print e.color_set.all()

Вместо того, чтобы делать n, запросы будут делать 2, один для записей и один для поиска по внешнему ключу

Как я уже говорил ранее, если вам просто нужны все цвета Entry вместе вы можете выбрать все Color объекты и заказать их на entry:

colors = Color.objects.order_by('entry')

Теперь вы можете зациклить эти объекты и распечатать их так, как вы хотите:

for color in colors:
    print(color.entry.user, color.color)

# john, blue
# john, orange
# bob, green

Или вы можете извлечь эту информацию как values_list

color_entries = list(colors.values_list('entry__user', 'color'))
# [('john', 'blue'), ('john', 'orange'), ('bob', 'green'), ...]
Другие вопросы по тегам