Эффективная пагинация от Join in Django - PullRequest
2 голосов
/ 07 декабря 2009

У меня здесь проблема с объединением и разбиением на страницы. У меня есть 3 модели:

  • Pad
  • Tag
  • TagRelation

Я использую отношение Tag для управления отношениями ManyToMany между пэдами и тегами (с атрибутом - поля ManyToMany). Теперь, когда я делаю соединение в таблицах Pad и Tag, это дает мне что-то вроде этого ...

pad.name   tag.name     etc
---------------------------
pad1       tag1         ...
pad1       tag2         ...
pad2       tag3         ...

Теперь, когда я создаю объект Paginator () из этих результатов, это явно неправильный счетчик элементов на странице. Я должен был бы перебрать ВСЕ результаты и создать словарь, подобный этому ...

[{name:'pad1', tags:['tag1', 'tag2']}, {name:'pad2' ....]

... и используйте Paginator для получения правильных страниц.

Каков наилучший подход к этой проблеме? Я мог бы сделать запрос БД для каждого объекта Pad на текущей странице, чтобы получить его теги, но я предполагаю, что это рано или поздно убьет сервер (должен быть быстродействующим).

Содержание результатов также может быть довольно длинным, и итерация по всему набору будет стоить много системной памяти (или это? Просветит меня :)).

1 Ответ

3 голосов
/ 07 декабря 2009

Если я правильно понимаю, вы должны выполнить разбиение на страницы на Pad.objects.all (), а затем использовать select_related на объектах TagRelation в обоих случаях, чтобы получить соответствующие теги всего за один (дополнительный) запрос, и используя эти данные в вашем представлении / шаблон. Что-то вроде:

thispagepadids = [o.id for o in mypageobject.object_list]
tagrels = TagRelation.objects.filter(pad__id__in=thispagetagids).select_related('tag','pad'))

(при условии, что у вас есть объект страницы в mypageobject). Затем вы можете получить pad и тег для любого данного тега в коде (использование шаблона шаблона regroup , вероятно, является самым простым способом сделать это), но БД выполняет только один (гигантский) запрос, и ваш счетчик нумерации страниц все еще правильно.

Обратите внимание, что нам пришлось выполнить 2 запроса, потому что вы не можете просто использовать select_related непосредственно в поле многие ко многим (см. этот билет ), но вы можете использовать его, чтобы следовать за FK в обе стороны от промежуточной таблицы m2m.

...