你如何优化Django Auth查询?

时间:2015-07-01 08:37:19

标签: django django-rest-framework django-authentication

我已经使用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不同,因为它没有引用内置的身份验证模型。它是我尝试使用的内置身份验证模型。

1 个答案:

答案 0 :(得分:1)

您可以使用formfield_for_manytomanyhttps://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)