Отслеживание вложенных внешних ключей при предварительной выборке в Django

#django #nested #prefetch

#django #вложенный #предварительная выборка

Вопрос:

У меня есть информационная модель с глубокими и сложными отношениями внешнего ключа. и их много. Из-за этого я пытаюсь использовать select_related() и prefetch_related() для минимизации количества запросов к моей базе данных.

Однако у меня проблема в том, что я не могу найти способ заставить операторы предварительной выборки следовать за внешними ключами на произвольную глубину. Я знаю об операторе двойного подчеркивания ( __ ), но на самом деле это не вариант, потому что я заранее не знаю, насколько глубокой будет вложенность.

Итак, допустим, у меня есть объекты A, B, C,...Z . Любой объект может иметь произвольное количество внешних ключей, указывающих на любой объект, который появляется, скажем, позже в алфавите. Как я могу убедиться, что, например, предварительная выборка внешнего ключа, который A указывает на B , будет следовать за всеми внешними ключами в B?

Моим лучшим решением на данный момент был полужестко закодированный подход к get_queryset() методу диспетчера объектов.

Заранее благодарю вас

Редактировать:

Хорошо, итак, идея о том, как я пытаюсь это сделать на данный момент, заключается в следующем:

     class MyModelmanager(model.Manger):
        def get_queryset()
            qs = super().get_queryset()
            qs = qs.select_related(*thefiledsiwannaprefetch)
            return qs
  

Теперь в полях, которые я предварительно выбираю, есть отношения внешних ключей, за которыми я хотел бы следить. Как мне этого добиться (без использования '__' )?

РЕДАКТИРОВАТЬ 2

Другая попытка была следующей:

     class MyModelmanager(model.Manger):
        def get_queryset()
            return super().get_queryset().prefetch_related()
  

Затем я переопределил управление другими моделями, чтобы они также выполняли предварительную выборку в своем get_queryset() методе. Это также не сработало.

Комментарии:

1. Опубликуйте код того, как вы пытаетесь это сделать.

2. Если вы выполняете сериализацию, у DRF есть depth . Если вы отправляете данные в шаблон, в какой-то момент кода вы действительно что-то сделаете с данными, и обычно именно здесь вы создаете запросы для извлечения нужных вам данных, не меньше и не больше. Описанный подход по существу извлекает все данные из базы данных. Интересно, каким может быть вариант использования для этого. В любом случае, вам потребуется отражение , чтобы сделать это с prefetch_related .

Ответ №1:

Из документов:

Могут возникнуть ситуации, когда вы захотите вызвать select_related() с большим количеством связанных объектов или когда вы не знаете всех отношений. В этих случаях можно вызвать select_related() без аргументов. Это будет следовать за всеми ненулевыми внешними ключами, которые он может найти — должны быть указаны внешние ключи с возможностью обнуления. В большинстве случаев это не рекомендуется, поскольку это, вероятно, усложнит базовый запрос и вернет больше данных, чем на самом деле необходимо.

Комментарии:

1. Ага, видел это. Я также пытался и потерпел неудачу с треском. Есть предложения о том, как это было бы реализовано на практике?

2. Вы вызвали без каких-либо аргументов, и это не сработало?

3. Чтобы было ясно, это не относится к prefetch_related . Пустой prefetch_related вызов ничего не делает.