首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >如何优化Django Auth查询?

如何优化Django Auth查询?
EN

Stack Overflow用户
提问于 2015-07-01 16:37:19
回答 2查看 802关注 0票数 4

我已经使用Django Rest Framework将用户模型从django.contrib.auth.models转换为应用编程接口。当我在API中执行User.objects.all()查询时,每次调用API时,我都会得到数百个这样的查询:

代码语言:javascript
复制
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优化这些问题,最后得到了这个查询:

代码语言:javascript
复制
User.objects.all().prefetch_related('user_permissions__content_type__id')

但它会产生以下错误:

代码语言:javascript
复制
'user_permissions__content_type__id' does not resolve to an item that supports 
prefetching - this is an invalid parameter to prefetch_related().

那么,如何将查询数从数百个减少到通常可以优化django rest框架的5到6个呢?

为了便于记录,以下是我的完整代码(出于相关性考虑,进行了删节):

代码语言:javascript
复制
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模型。

EN

回答 2

Stack Overflow用户

发布于 2019-04-30 20:06:51

您可以使用formfield_for_manytomany (https://docs.djangoproject.com/en/2.2/ref/contrib/admin/#django.contrib.admin.ModelAdmin.formfield_for_manytomany),查询所有权限,选择相关content_type。

代码语言:javascript
复制
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)
票数 2
EN

Stack Overflow用户

发布于 2021-09-11 03:23:43

如果您使用的是自定义用户模型,则需要通过继承UserAdmin来设置您的管理模型。否则,您将有大量的查询生成,并大大减慢您的管理面板。

下面是一个例子:

代码语言:javascript
复制
from django.contrib.auth.admin import UserAdmin


@admin.register(models.AuthUser)
class AuthUserAdmin(UserAdmin):
    list_display = ['date_joined', 'username', 'email', 'is_staff', 'is_superuser']
    list_filter = ('is_staff', 'is_superuser')
    ordering = ['-username']
    search_fields = ['username', ]
    read_only_exclude = ('', )
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/31156415

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档