我已经使用Django Rest Framework将用户模型从django.contrib.auth.models转换为API。当我在API中执行User.objects.all()查询时,每次调用API时,我都会遇到数百个这样的查询:
SELECT `django_content_type`.`id`,
`django_content_type`.`app_label`,
`django_content_type`.`model`
FROM `django_content_type`
WHERE `django_content_type`.`id` = 2
因此,用户API非常慢。
尝试使用prefetch_related优化那些我用这个查询结束:
User.objects.all().prefetch_related('user_permissions__content_type__id')
但它会产生错误:
'user_permissions__content_type__id' does not resolve to an item that supports
prefetching - this is an invalid parameter to prefetch_related().
那么如何将查询数量从数百个减少到五个或六个我通常可以优化django rest框架到?
为了记录,这是我的完整代码(删除相关性):
from rest_framework import viewsets
from django.contrib.auth.models import User
class UserViewSet(viewsets.ModelViewSet):
model = User
filter_fields = ('username',)
def get_queryset(self):
if self.request.user.is_staff:
return User.objects.all().prefetch_related('user_permissions__content_type__id')
注意:this similar question不同,因为它不是指内置的auth模型。这是我试图使用的内置auth模型。
您可以使用formfield_for_manytomany
(https://docs.djangoproject.com/en/2.2/ref/contrib/admin/#django.contrib.admin.ModelAdmin.formfield_for_manytomany),查询所有权限并选择相关的content_type。
from django.contrib import admin
from django.contrib.auth.models import User, Permission
@admin.register(User)
class UserAdmin(admin.ModelAdmin):
def formfield_for_manytomany(self, db_field, request, **kwargs):
if db_field.name == 'user_permissions':
kwargs['queryset'] = Permission.objects.all().select_related('content_type')
return super().formfield_for_manytomany(db_field, request, **kwargs)