Django:UpdateView - 调度:减少查询数量

use*_*631 1 django django-orm django-class-based-views

我有一个产品模型、公司模型的外键、用户的单键。

我重写调度(方法)来检查用户是否有权编辑对象(产品)。

我正在尝试优化对数据库的查询,因为其中一些是重复的。

def dispatch(self, request, *args, **kwargs):
    obj = self.get_object()
    if obj.company.user != request.user:
        raise PermissionDenied
    else:
        print('ok')
        return super().dispatch(request, *args, *kwargs)
Run Code Online (Sandbox Code Playgroud)

查询产品

obj = self.get_object() 
Run Code Online (Sandbox Code Playgroud)

向公司查询和向用户查询两次

if obj.company.user != request.user:
Run Code Online (Sandbox Code Playgroud)

再次查询产品

 return super().dispatch(request, *args, *kwargs)
Run Code Online (Sandbox Code Playgroud)

如何优化和删除重复查询?

Ala*_*air 5

您可以通过比较 id 而不是模型实例来阻止用户查询之一。

if obj.company.user_id != request.user.id:
Run Code Online (Sandbox Code Playgroud)

进一步减少查询数量更为棘手。在实践中,删除重复查询不会产生明显的效果,并且可能不值得使代码复杂化。

为了防止重复对象查找,您可以将对象缓存为self.object.

def dispatch(self, request, *args, **kwargs):
    self.obj = self.get_object()
        if obj.company.user != request.user:
        raise PermissionDenied
Run Code Online (Sandbox Code Playgroud)

然后重写 thenget_object首先检查缓存。

def get_object(self, queryset=None):
    obj = getattr(self, 'object', None)
    if obj is None:
        obj = super().get_object(queryset)
    return obj
Run Code Online (Sandbox Code Playgroud)

select_related()您可以通过在获取对象时使用来摆脱公司查询。同样,这将使代码变得更加复杂,并且可能不值得这样做。