Избегайте проблем с N + 1 при получении пользователей и разрешений в Django - PullRequest
0 голосов
/ 02 ноября 2018

Мне нужно получить список пользователей и список разрешений (разрешений объектов-хранителей), которые есть у каждого пользователя. Проблема в том, что каждый способ, которым я пытаюсь это сделать, наталкивается на проблему N + 1. Просто ли я перебираю список пользователей и получаю разрешения из набора

for user in User.objects.all():
    data = UserSerializer(user).data
    data['permissions'] = PermissionSerializer(user.userobjectpermission_set, many=True)

Или если я использую prefetch_related ()

for user in User.objects.prefetch_related('userobjectpermission_set'):
    data = UserAndPermSerializer(user).data

В конечном итоге происходит выборка списка пользователей, а затем выполнение отдельного запроса на разрешение для каждого пользователя.

Я могу написать необработанный оператор SQL и сериализовать его самостоятельно, но я бы предпочел использовать уже имеющиеся у меня сериализаторы, и поэтому я хотел бы, чтобы пользователи и разрешения использовались в качестве экземпляров модели. Любой способ сделать то, что мне нужно, используя ORM?

Django - это версия 1.11 LTS, и я не могу обновиться до 2.x в ближайшее время.

1 Ответ

0 голосов
/ 03 ноября 2018

Если вы устанавливаете приоритеты чтения из базы данных над такими вещами, как удобочитаемость, удобство обслуживания и эффективность для разработчика, вы можете сделать это в два чтения:

  • читать всем пользователям: User objects.all ()
  • читать все разрешения: Permission.objects.all ()

Затем прошейте разрешения для пользователя на уровне приложения.

Это отстой, но это эффективно при чтении из базы данных

...