我使用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"
)