2

プラグインを使用して新しい Django 2.2 プロジェクトを作成していますnplusone( https://github.com/jmcarp/nplusone )。/admin URL に移動しようとすると、次のエラー「潜在的な不要な熱心な負荷が検出されましたLogEntry.user」が表示されます。この問題は、DB に少なくとも 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)

DEBUG 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,)
4

1 に答える 1

3

N+1 が Django 管理者に満足することはめったにないことがわかりました。関連するエントリ (ユーザー グループなど) が遅延して読み込まれ、大きなリストで N+1 問題が発生するか、それらが prefetched() されてからシングル ユーザー ページに表示されます。 「不要な熱心な負荷」が検出されたこと。

問題は、リスト ページと単一オブジェクト ページに同じ基本 ModelAdmin クエリセットが使用されるため、両方の問題を回避することは容易ではありません。

管理ページごとに異なる「プリフェッチ」クエリセットを作成する簡単な解決策が誰かに提供されるまで、私はこれらのモデルをホワイトリストに登録しました。これらの管理ページで N+1 リクエストが発生していないことを django デバッグ ツールバーで確認してください。

NPLUSONE_WHITELIST = [
    {"model": "admin.LogEntry", "field": "user"},
    {"model": "accounts.User", "field": "groups"},
]
于 2019-05-31T11:45:25.620 に答える