Django技术问题:如何为多个Job筛选符合条件的当前Task?
嘿,针对你这个工作流管理网站里筛选多个Job当前Task的需求,我来给你几个实用的解决方案!
首先先明确咱们的核心规则:每个Job的当前Task是其下属所有Task中,按步骤顺序(step.order)排序后,第一个没有设置「完成日期」的Task;如果所有Task都有完成日期,这个Job就处于已完成状态,没有当前Task。
1. 数据库层面直接筛选(SQL方案)
如果数据量不小,直接在数据库层做筛选效率最高。这里以PostgreSQL为例,用窗口函数就能轻松实现:
WITH ranked_tasks AS ( SELECT j.id AS job_id, t.id AS task_id, t.step_id, s.order AS step_order, t.completion_date, -- 按Job分组,给每个Job的Task按步骤顺序排号 ROW_NUMBER() OVER ( PARTITION BY j.id ORDER BY s.order ASC ) AS row_num FROM jobs j JOIN tasks t ON j.id = t.job_id JOIN steps s ON t.step_id = s.id ) SELECT job_id, task_id, step_id, step_order FROM ranked_tasks WHERE completion_date IS NULL AND row_num = 1;
这个查询会先给每个Job的Task按步骤顺序排好名次,然后精准揪出每个Job里排名第一且未完成的Task。如果某个Job的所有Task都已完成,它就不会出现在结果里。
2. ORM框架实现(以Django为例)
如果用Python Django这类ORM框架开发,也能通过子查询实现类似逻辑,不用写原生SQL:
from django.db.models import Subquery, OuterRef # 先定义子查询:获取每个Job对应的首个未完成Task ID first_uncompleted_task = Task.objects.filter( job_id=OuterRef('id'), completion_date__isnull=True ).order_by('step__order').values('id')[:1] # 关联查询Job和对应的当前Task jobs_with_current_task = Job.objects.annotate( current_task_id=Subquery(first_uncompleted_task) ).filter(current_task_id__isnull=False)
这样你就能拿到所有存在未完成当前Task的Job,还能直接获取到对应Task的ID,后续关联查询Task详情也很方便。
3. 应用层代码逻辑筛选
如果是在代码里处理已经查询出来的Job和Task数据(比如小数据量场景),可以用简单的遍历逻辑实现:
def get_current_task_map(jobs): job_current_task = {} for job in jobs: # 按步骤顺序给当前Job的Task排序 sorted_tasks = sorted(job.tasks.all(), key=lambda t: t.step.order) # 找到第一个未完成的Task current_task = next( (task for task in sorted_tasks if task.completion_date is None), None ) if current_task: job_current_task[job.id] = current_task return job_current_task
这个函数会返回一个字典,key是Job的ID,value是对应的当前Task,已完成的Job不会出现在字典中。
额外小提示
- 如果要筛选特定条件的Job(比如属于某个Workflow、创建时间在某个范围),只需要在上述查询中添加对应的过滤条件就行,比如SQL里加
AND j.workflow_id = 100,ORM里加.filter(workflow__id=100)。 - 数据量大的话,记得给
tasks.job_id、tasks.completion_date、steps.order这些字段加索引,能大幅提升查询速度。
内容的提问来源于stack exchange,提问作者Johannes
相关产品推荐
相关产品推荐

