首页 > 解决方案 > Django在过滤的模型实例组中获取最大字段值

问题描述

我需要一些帮助来在我的视图中创建自定义 Django 查询。我有两个模型,部门和团队,每个部门可以有多个团队。用户可以按任何顺序手动对 Teams 进行排序,一旦完成,每个 Team 实例上的 order 字段都会更新。因此,现在创建新团队时,我希望在特定部门中获得最大的 Team.order 值。

下面的这部分返回所有 Team 实例Team.objects.filter(department=team.department.id),但是我如何从 order 字段中获取最大值(循环除外)?

看法

class TeamCreate(LoginRequiredMixin, CreateView):
    model = Team
    form_class = TeamForm
    template_name = 'app/sidebar_team.html'

    # def get_initial(self):
    def get_initial(self):
        pk = self.request.GET.get('id')
        return {
            'department': pk,
        }

    def post(self, request, *args, **kwargs):
        form = TeamForm(request.POST)
        if form.is_valid():
            team = form.save(commit=False)
            team.author = request.user
            team.modified_date = timezone.now()

            # Get max Team.order value, increment by one, and set as new team.order
            max = Team.objects.filter(department=team.department.id).extra(Max('order'))

            team.save()
            return redirect('/dashboard/' + str(team.department.id))

        else:
            return redirect('/dashboard/' + str(form.department.id))

标签: django

解决方案


如果您想将整个项目集合“折叠”成一个或多个值,这称为.aggregate(..)[django-doc]。所以我们可以写一个像这样的聚合:

Team.objects.filter(
    department=team.department.id
).aggregate(
    max_order=Max('order')
)['max_order']

.aggregate(..)执行查询,并返回带有聚合结果的字典。由于这里我们只做一个聚合(使用 as name max_order),因此字典包含该元素。因此,我们可以使用['max_order'].

请注意,如果没有与过滤器匹配的行(或者根本没有 Teams),这将返回一个字典,其中 with as value None。因此,您将需要解决此问题。因此,例如,如果根本没有Teams,那么Team.objects.filter(..).agregate(..)将返回{'max_order': None}。然后由您来解决这种情况。


推荐阅读