Как исправить ошибку «Обнаружена потенциальная ненужная нагрузка на« LogEntry.user »» - PullRequest
1 голос
/ 30 апреля 2019

Я создаю новый проект Django 2.2 с плагином nplusone (https://github.com/jmcarp/nplusone).. Когда я пытаюсь зайти на / admin URL, я получаю следующую ошибку «Обнаружена потенциальная ненужная нагрузка на LogEntry.user».проблема возникает, когда у меня есть хотя бы 1 запись в БД.

models.py

class Post(models.Model):
    author = models.ForeignKey(User,
                               on_delete=models.CASCADE)
    title = models.CharField(max_length=200)
    created_date = models.DateTimeField(auto_now_add=True)
    body = models.TextField()
    slug = models.SlugField(max_length=100, unique=True)
    preview_image = models.ImageField(upload_to='images', blank=True)

    class Meta:
        verbose_name = 'Post'
        verbose_name_plural = 'Posts'
        ordering = ['-id']

    def __str__(self):
        return self.title

    def get_absolute_url(self):
        return reverse('post', args=(self.slug,))

admin.py

admin.site.register(Post, PostAdmin)

ОТЛАДКА SQL

SELECT "django_session"."session_key", "django_session"."session_data", "django_session"."expire_date" FROM "django_session" WHERE ("django_session"."expire_date" > '2019-04-30 06:11:28.376554' AND "django_session"."session_key" = 'hbwpegj1vpvkv5wdkbqr38ty55s3cm38'); args=('2019-04-30 06:11:28.376554', 'hbwpegj1vpvkv5wdkbqr38ty55s3cm38')
SELECT "auth_user"."id", "auth_user"."password", "auth_user"."last_login", "auth_user"."is_superuser", "auth_user"."username", "auth_user"."first_name", "auth_user"."last_name", "auth_user"."email", "auth_user"."is_staff", "auth_user"."is_active", "auth_user"."date_joined" FROM "auth_user" WHERE "auth_user"."id" = 1; args=(1,)
SELECT "django_admin_log"."id", "django_admin_log"."action_time", "django_admin_log"."user_id", "django_admin_log"."content_type_id", "django_admin_log"."object_id", "django_admin_log"."object_repr", "django_admin_log"."action_flag", "django_admin_log"."change_message", "auth_user"."id", "auth_user"."password", "auth_user"."last_login", "auth_user"."is_superuser", "auth_user"."username", "auth_user"."first_name", "auth_user"."last_name", "auth_user"."email", "auth_user"."is_staff", "auth_user"."is_active", "auth_user"."date_joined", "django_content_type"."id", "django_content_type"."app_label", "django_content_type"."model" FROM "django_admin_log" INNER JOIN "auth_user" ON ("django_admin_log"."user_id" = "auth_user"."id") LEFT OUTER JOIN "django_content_type" ON ("django_admin_log"."content_type_id" = "django_content_type"."id") WHERE "django_admin_log"."user_id" = 1 ORDER BY "django_admin_log"."action_time" DESC  LIMIT 10; args=(1,)

1 Ответ

1 голос
/ 31 мая 2019

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

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

Пока кто-то не придет с простым решением для создания различных наборов запросов "предварительной выборки" для разных страниц администратора, я включил эти модели в белый список.Просто проверьте с помощью панели инструментов отладки django, что на этих страницах администратора не происходит N + 1 запросов.

NPLUSONE_WHITELIST = [
    {"model": "admin.LogEntry", "field": "user"},
    {"model": "accounts.User", "field": "groups"},
]
...