这应该可以通过创建Task
一个与两组 User 有关系的新工作流类型来实现Group
(例如,a/b 或之前/之后,最好在模型定义中保持这个通用性)。
这个新Task
的可以作为Workflow
Wagtail 管理员中新的一部分创建,并且每个组都链接到版主组 1 / 2。
Wagtail 上的方法Task
允许您根据Page
模型为任何创建的工作流返回批准选项,从这里您可以查找将在类上的方法并从那里分配组。
使用更多通用方法的好处是,您可以将其用于任何主持人分配的拆分,作为未来工作流任务的一部分。
实施概述
- 1 - 阅读有关如何添加新任务类型和
Task
模型参考的 Wagatail 文档以了解此过程。
- 2 - 通读内置代码中的完整实现
GroupApprovalTask
。
- 3 - 在
GroupApprovalTask
您可以看到,具有覆盖的方法都依赖于检查,self.groups
但它们都将page
作为 arg 传入这些方法。
- 4 - 创建一个新
Task
的扩展 WagtailTask
类并在此模型上创建两个ManyToManyField
允许链接两组用户组(注意:您不必将此作为两个字段,您可以将模型放在中间,但下面的示例只是进入监狱的最简单方法)。
- 5 - 在
DailyReflectionPage
模型上创建一个方法,该方法get_approval_group_key
可能会根据您上面描述的业务需求返回一个简单的布尔值或“A”或“B”(检查模型的日期等)
- 6 - 在您的自定义
Task
中创建一个抽象检查Page
此方法的方法并返回任务的用户组。您可能想要添加一些错误处理和默认值。例如get_approval_groups
- 7 - 为与页面一起调用并返回值的每个 'start'、'user_can_access_editor'、、、、、方法添加一个自定义方法(请参阅代码
page_locked_for_user
了解这些应该做什么。user_can_lock
user_can_unlock
get_task_states_user_can_moderate
get_approval_group
GroupApprovalTask
示例代码片段
模型.py
class DailyReflectionPage(Page):
"""
The Daily Reflection Model
"""
def get_approval_group_key(self):
# custom logic here that checks all the date stuff
if date_is_after_foo:
return 'A'
return 'B'
class SplitGroupApprovalTask(Task):
## note: this is the simplest approach, two fields of linked groups, you could further refine this approach as needed.
groups_a = models.ManyToManyField(
Group,
help_text="Pages at this step in a workflow will be moderated or approved by these groups of users",
related_name="split_task_group_a",
)
groups_b = models.ManyToManyField(
Group,
help_text="Pages at this step in a workflow will be moderated or approved by these groups of users",
related_name="split_task_group_b",
)
admin_form_fields = Task.admin_form_fields + ["groups_a", "groups_b"]
admin_form_widgets = {
"groups_a": forms.CheckboxSelectMultiple,
"groups_b": forms.CheckboxSelectMultiple,
}
def get_approval_groups(self, page):
"""This method gets used by all checks when determining what group to allow/assign this Task to"""
# recommend some checks here, what if `get_approval_group` is not on the Page?
approval_group = page.specific.get_approval_group_key()
if (approval_group == 'A'):
return self.group_a
return self.group_b
# each of the following methods will need to be implemented, all checking for the correct groups for the Page when called
# def start(self, ...etc)
# def user_can_access_editor(self, ...etc)
# def page_locked_for_user(self, ...etc)
# def user_can_lock(self, ...etc)
# def user_can_unlock(self, ...etc)
def get_task_states_user_can_moderate(self, user, **kwargs):
# Note: this has not been tested, however as this method does not get `page` we must find all the tasks allowed indirectly via their TaskState pages
tasks = TaskState.objects.filter(status=TaskState.STATUS_IN_PROGRESS, task=self.task_ptr)
filtered_tasks = []
for task in tasks:
page = task.select_related('page_revision', 'task', 'page_revision__page')
groups = self.get_approval_groups(page)
if groups.filter(id__in=user.groups.all()).exists() or user.is_superuser:
filtered_tasks.append(task)
return TaskState.objects.filter(pk__in=[task.pk for task in filtered_tasks])
def get_actions(self, page, user):
# essentially a copy of this method on `GroupApprovalTask` but with the ability to have a dynamic 'group' returned.
approval_groups = self.get_approval_groups(page)
if approval_groups.filter(id__in=user.groups.all()).exists() or user.is_superuser:
return [
('reject', "Request changes", True),
('approve', "Approve", False),
('approve', "Approve with comment", True),
]
return super().get_actions(page, user)