Django admin prefetch content_type model



我使用django调试工具栏来分析为什么在django管理中对usermodel的调用如此缓慢。在这里,我看到有数百个对content_type模型的重复调用:

SELECT••••FROM django_content_type"在"django_content_type"!"id"= 1极限21362个类似查询。重复4次

老实说,我不明白这些调用是从哪里来的,但我想pre_fetch模型。然而,这似乎不可能以正常的方式实现,因为模型之间实际上没有ForeignKey或任何其他类型的直接关系。如何减少这362次content_type调用?

这是正在讨论的用户模型:

class User(AbstractBaseUser, PermissionsMixin):
"""
Base model for the user application
"""
USERNAME_FIELD = "email"
objects = UserManager()
username_validator = None
username = None
email = models.EmailField(_("email address"), unique=True)
is_staff = models.BooleanField(default=False)
is_active = models.BooleanField(default=True)
date_joined = models.DateTimeField(default=timezone.now)    
first_name = models.CharField(max_length=150, blank=True)
last_name = models.CharField(max_length=150, blank=True)
title_of_person = models.ForeignKey(
TitleOfPerson, on_delete=models.CASCADE, blank=True, null=True
)
is_verified = models.BooleanField(default=False)
language = models.ForeignKey(
Language, blank=True, null=True, on_delete=models.SET_NULL
)
created_at = models.DateTimeField(auto_now_add=True)
updated_at = models.DateTimeField(auto_now=True)
class Meta:
verbose_name = _("User")
verbose_name_plural = _("Users")
def __str__(self) -> str:
return self.email

感谢

在您的UserAdmin类中,为您的User模型添加UserCreationForm。如,

from django.contrib.auth.admin import (
UserAdmin as BaseUserAdmin, UserChangeForm as BaseUserChangeForm,
UserCreationForm as BaseUserCreationForm
)
class UserChangeForm(BaseUserChangeForm):
class Meta:
model = User
fields = '__all__'
def clean_email(self):
data = self.cleaned_data.get('email')
return data.lower()
class UserAdmin(BaseUserAdmin):
form = UserChangeForm
... other fields...

这将解决您的查询问题。

解决问题的实际部分:

在默认的UserChangeForm中,在__init__方法中,user_permissions查询集正在使用select_related优化进行初始化。

class UserChangeForm(forms.ModelForm):
password = ReadOnlyPasswordHashField(
label=_("Password"),
help_text=_(
"Raw passwords are not stored, so there is no way to see this "
"user’s password, but you can change the password using "
'<a href="{}">this form</a>.'
),
)
class Meta:
model = User
fields = "__all__"
field_classes = {"username": UsernameField}
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
password = self.fields.get("password")
if password:
password.help_text = password.help_text.format("../password/")
user_permissions = self.fields.get("user_permissions")
if user_permissions:
user_permissions.queryset = 
user_permissions.queryset.select_related(
"content_type"
)

相关内容

最新更新