我正在开发一个Django
web应用程序,用户可以在该应用程序中创建任务列表。每个任务都是数据库中的一个记录(即:Django对象(,用户可以为每个任务分配优先级。
如果用户创建了10个任务,每个任务的优先级将从1到10。我正在努力寻找一种有效的方法,允许用户更改任务的优先级以及插入和删除任务。例如:
- 用户将任务优先级从3降低到7。其他任务的优先级需要相应调整
- 用户删除优先级为4的任务。其余任务的优先次序需要再次调整
- 用户插入优先级为5的新任务。这意味着从优先事项5开始的现有任务需要转移
是否有任何设计模式或建议,说明如何根据每个项目的优先级管理本质上相当于队列的内容,同时允许用户:
- 在优先级列表中上下移动任务
- 删除任务
- 添加具有指定优先级的新任务
您不必为优先级分配数字。你可以使用理论上具有无限分辨率的字符串。
item index
-----------------
gizmo 1
<<------ Oh no! no room between 1 and 2.
This requires incrementing _every_ item after it
gadget 2
gear 3
toolkit 4
box 5
但如果你按100计算,这里是
item index
-----------------
gizmo 100
<<------ Sweet :). I can re-order 99 (!) items here
without having to change anything else
gadget 200
gear 300
toolkit 400
box 500
更好的是:以下是Jira如何解决这个问题。他们的";等级;(您称之为index(是一个字符串值,它允许在排序项目之间有很大的喘息空间。
下面是一个我使用的jira数据库的真实例子
id | jira_rank
---------+------------
AP-2405 | 0|hzztxk:
ES-213 | 0|hzztxs:
AP-2660 | 0|hzztzc:
AP-2688 | 0|hzztzk:
AP-2643 | 0|hzztzs:
AP-2208 | 0|hzztzw:
AP-2700 | 0|hzztzy:
AP-2702 | 0|hzztzz:
AP-2411 | 0|hzztzz:i
AP-2440 | 0|hzztzz:r
注意这个例子hzztzz:i。字符串排名的优点是,你在两个项目之间的空间用完了,你仍然不必重新排名其他任何项目。您只需要开始在字符串中添加更多字符来缩小焦点。基于这里的答案
虽然说这个包使用得很好,但它实际上使用了一个正整数,并发出SQL来更新以下所有订单号。
为什么要如此努力地构建队列?你不能直接使用.order_by吗
假设这是您的型号:
class Task(models.Model):
user = models.ForeignKey(User)
priority = models.IntegerField()
created = models.DateTimeField(auto_now=True)
然后,当你需要一个用户的所有任务列表时,你可以只做
qs = Task.objects.filter(user=your_user_instance).order_by('-priority', 'created')
现在,变量qs是一个迭代器,它首先列出优先级最高的任务(如果两个任务具有相同的优先级,它将首先列出旧的任务(
以下是我如何为解决上述问题
task_order_list = self.request.POST.get("task_order_list",'[]')
task_order_list = json.loads(task_order_list)
task_qs = Task.objects.all()
for priority,id in enumerate(task_order_list):
task_qs.filter(id=id).update(priority=priority)
对于上面的代码段,假设:
任务id的实际列表:[1,2,3,4,5]
输入:
新列表:[5,3,2,4,1]
输出:
更新列表:[5,3,2,4,1]