Django:如何跟踪线性(但灵活)项目管理工作流?

Django:如何跟踪线性(但灵活)项目管理工作流?,django,project-management,workflow,data-modeling,django-authentication,Django,Project Management,Workflow,Data Modeling,Django Authentication,我正在Django中开发一个项目管理应用程序,它需要一个涉及不同用户组(如Django auth组)的线性响应过程。响应过程中的每个步骤都有几个响应选项(该步骤特有的大多数选项),并分配给特定组中的用户。该过程的下一步由用户的响应决定,有时可能需要从项目的一个成员处请求额外的信息 问题是,我目前的实施似乎相当繁琐,我确信有更好的方法跟踪响应过程。我希望有人能提供一些关于更强大解决方案的见解 作为一个简单的例子,考虑一个具有下列用户组的项目:销售代表、销售经理和项目经理。当前的模型如下所示: cl

我正在Django中开发一个项目管理应用程序,它需要一个涉及不同用户组(如Django auth组)的线性响应过程。响应过程中的每个步骤都有几个响应选项(该步骤特有的大多数选项),并分配给特定组中的用户。该过程的下一步由用户的响应决定,有时可能需要从项目的一个成员处请求额外的信息

问题是,我目前的实施似乎相当繁琐,我确信有更好的方法跟踪响应过程。我希望有人能提供一些关于更强大解决方案的见解

作为一个简单的例子,考虑一个具有下列用户组的项目:销售代表、销售经理和项目经理。当前的模型如下所示:

class Project(models.Model):  
    assigned_to = models.ForeignKey(User, related_name="projects_assigned_to") #Indicates which user needs to respond next.  Will be sales_rep, sales_mgr, or project_mgr.
    sales_rep = models.ForeignKey(User, related_name="sales_rep_projects") #choices limited to "Sales Rep" Group  
    sales_mgr = models.ForeignKey(User, related_name="sales_mgr_projects") #choices limited to "Sales Manager" Group 
    project_mgr = models.ForeignKey(User, related_name="project_mgr_projects") #choices limited to "Project Manager" Group
    current_step = models.ForeignKey(Step, related_name="projects_with_current_step")
    previous_step = models.ForeignKey(Step, related_name="projects_with_previous_step")
    status = models.ForeignKey(Status) #Automatically assigned according to the user's response.  Includes things like "On Track", "On Hold", "Rejected", "Accepted", etc.

class Step(models.Model):
    name = models.CharField(max_length=50) 

class Status(models.Model):
    name = models.CharField(max_length=50) 
class Response(models.Model):
    comment = models.TextField()
    response_action = models.ForeignKey(ResponseAction)
    submitted = models.DateTimeField()

class ResponseAction(models.Model):
     """ I.e. 'Sales Manager approved the project', 'Project Manager commenced the project'"""  
     name = models.CharField(max_length=100)
以下是该流程如何工作的简单概述:

  • 销售代表创建一个新项目并将其分配给销售经理
  • 销售经理将看到以下选项:
    (a) 批准项目或
    (b) 向销售代表索取更多信息
  • 如果项目获得批准,则分配给项目经理,项目经理将获得以下选项:
    (a) 开始项目
    (b) 拒绝该项目
    (c) 向销售代表或销售经理索取更多信息
  • 如果向用户请求更多信息,项目将分配给该用户,用户只需提供文本框响应即可。但是,一旦收到他们的响应,项目就需要返回到上一步(这就是为什么我要跟踪上面的当前步骤和上一步)。在本例中,如果项目经理向销售代表请求更多信息,则一旦销售代表做出响应,项目应分配回项目经理,并使用他之前拥有的相同响应选项(开始、拒绝、请求更多信息)
  • 整个过程大约有10个这样的步骤

    要使事情复杂化,我还需要能够显示为每个步骤选择的响应。例如,如果销售经理批准了项目,则应显示“销售经理批准了项目”以及他们可能有的任何评论。模型如下所示:

    class Project(models.Model):  
        assigned_to = models.ForeignKey(User, related_name="projects_assigned_to") #Indicates which user needs to respond next.  Will be sales_rep, sales_mgr, or project_mgr.
        sales_rep = models.ForeignKey(User, related_name="sales_rep_projects") #choices limited to "Sales Rep" Group  
        sales_mgr = models.ForeignKey(User, related_name="sales_mgr_projects") #choices limited to "Sales Manager" Group 
        project_mgr = models.ForeignKey(User, related_name="project_mgr_projects") #choices limited to "Project Manager" Group
        current_step = models.ForeignKey(Step, related_name="projects_with_current_step")
        previous_step = models.ForeignKey(Step, related_name="projects_with_previous_step")
        status = models.ForeignKey(Status) #Automatically assigned according to the user's response.  Includes things like "On Track", "On Hold", "Rejected", "Accepted", etc.
    
    class Step(models.Model):
        name = models.CharField(max_length=50) 
    
    class Status(models.Model):
        name = models.CharField(max_length=50) 
    
    class Response(models.Model):
        comment = models.TextField()
        response_action = models.ForeignKey(ResponseAction)
        submitted = models.DateTimeField()
    
    class ResponseAction(models.Model):
         """ I.e. 'Sales Manager approved the project', 'Project Manager commenced the project'"""  
         name = models.CharField(max_length=100)
    

    目前,视图中每个响应操作的逻辑都是硬编码的,并且一个步骤和另一个步骤之间没有正式的关系。我觉得应该使用更好的模型结构或数据结构来跟踪此工作流,但我已经在当前系统中工作了很长时间,因此很难用不同的方式来思考它。任何见解或灵感都将不胜感激!如果我需要澄清任何事情,请告诉我。

    更多地使用Step模型。您可以让它作为外键保存可能的后续步骤。通过这种方式,您可以通过更改数据来编辑流(例如,使用admin,而不是硬编码)。可能是这样的:

    class Step(models.Model):
        name = models.CharField(max_length=50)
        responsible_role = models.CharField(max_length=50) # this contains 'sales_rep', 'sales_mgr' etc
        allowed_actions = models.ManyToManyField('AllowedAction')
    
    class AllowedAction(models.Model):
        name = models.CharField(max_length=50)
        next_step = models.ForeignKey('Step') # the next step, if this action is chosen
    
    将实际项目历史记录分离到另一个模型:

    class ProjectHistoryStep(models.Model):
        timestamp = models.DateTimeField()
        step = models.ForeignKey('Step')
        project = models.ForeignKey('Project')  
    
    您可以使用此模型来跟踪项目的实际进度(不要忘记模型已经完成)


    您只需要一个处理所有逻辑的视图(它应该只调用Project类上的某个方法来执行实际工作)-检查项目现在处于什么状态(该项目的最新ProjectHistoryStep),以及用户的操作是什么,并相应地采取行动

    谢谢你的回复,这看起来真的很有希望!今天晚些时候我会玩玩它,让你知道它是怎么回事。我想让你做另外一件事。对于某些允许的操作,需要填写几个不同的字段。我应该在表单级别指定这些字段,还是为AllowedActionOption之类的内容创建另一个多个字段?感谢您的帮助。如果它很简单(例如,它们都是文本框,只是名称不同),那么您应该使用M2M从AllowedAction创建另一个模型。如果它更复杂(一些字段是FK到其他地方的,一些是文本,一些是URL等),那么使用django的表单,并在允许的操作中指定要使用的表单。这些字段更复杂,因此我将使用django表单路线。我喜欢在AllowedAction模型中指定form类的想法,但似乎我需要以某种方式在视图中将这些表单动态地组合成一个更大的表单。你能推荐一个解决方案吗?作为替代方案,我可以在步骤模型中指定form类,并创建一个包含所有字段的表单,但这种方法不是动态的,将字段与其允许的操作分开。不管怎样,我喜欢这个方向,并从您的帮助中受益匪浅。请看Alex Gaynor的精彩演讲:了解如何生成动态表单的一些想法。