2016-06-09 104 views
1

我有一个设置,我有几个模型其中两个是OptionProjectOptions代表我的应用程序中几个字段的选择选项,并存储大约1000(默认)值。我现在想要达到的是Projects可以有自己的一套Options,这意味着当他们开始一个新的Project时,他们将看到默认的选项集。然而他们可以删除一些选项,然后将不会显示在他们的项目(但留在数据库中)以及添加自定义选项到他们的项目(其他人不应该能够看到)。常见用例是用户可能希望保留默认Options的99%,以便它们将删除10并可能添加10.Django模型多对多替代

如何为描述的案例建模?我是否需要创建一个ManyToMany字段Project <-> Option,我将在创建项目时填充所有Options,或者是否有更好,更省空间的方式可供您考虑,例如:以某种方式存储删除的ID在某处,并找到一种方法来显示默认Options +项目特定Options

我的模型,像这样:

class Option(models.Model): 
    creator = models.ForeignKey(settings.AUTH_USER_MODEL, related_name="selectoptions", blank=True, null=True) 
    created = models.DateField(auto_now_add=True) 
    deleted = models.BooleanField(default=False) 

    name = models.CharField(max_length=255) 

    #we can have nested selectoptions 
    parent = models.ForeignKey('self', blank=True, null=True, related_name='children', db_index=True) 

class Project(models.Model): 
    name = models.CharField(max_length=200) 
    users = models.ManyToManyField(settings.AUTH_USER_MODEL, related_name='projects') 

回答

2

你可以有你的项目模型,例如

class Project(models.Model): 
    name = models.CharField(max_length=200) 
    options = models.ManyToManyField(Option, blank=True) 
    anyother field you wish to have 

,您可以与您可以选择的模式,应该足够了继续。

现在让我们说你有选择1,2,3,4,5和项目A和B

一个可以有选择1,2,3和可以有选择2,3, 4,5。

而且,你不希望有选择1项目一个,你只需从M2M领域被这句话

projectA.options.remove(option1) 

所以,你已经删除选项1,从项目中删除它,但它仍然存在在数据库中,你可以通过使用声明

projectB.options.add(option1) 

所以,现在当你做同样的选项1添加到项目B

projectA.options.all() 

你的输出就会选项2,选项3

projectB.options.all()会给选项1,选项2,选项3,选项4,选项5。

我希望我已经正确解释过,如果不清楚的话留下评论,会很乐意提供帮助。

编辑:是的,这是它应该如何应对您的情况,除非您获得替代方式。

编辑2

发布问题更新,你可以删除的选项,从项目M2M领域,并有通过名称ProjectOption一个单独的模型。它可能就像,

class ProjectOption(models.Model): 
    project = models.ForeignKey(Project) 
    option = models.ForeignKey(Option) 
    is_deleted = models.BooleanField(default=False) 

你仍然需要填充它,它是一次性操作。所以现在,每个项目都会有你的默认选项,如果用户选择删除一个,你可以设置is_deleted = True或实际删除它。这将为您提供删除选项的详细信息(仅当您不实际删除对象时,只需设置is_deleted = True)。

+0

问题是,当我创建一个新的项目时,我总是要做:'selectOptions = Option.objects.all()newProject.options.add(* selectOptions)'这将是一个巨大的开销,因为它会为所有项目创建数据库条目。我希望以某种方式存储已删除的selectoptions的ID,并且可能只接收来自默认项目的selectOptions +当前项目的selectOptions – niklas

+0

我可以知道这是一个问题吗?以及为什么你必须做newProject.options.add(* selectOptions)。看,选项是独立的实体。当你创建一个newProject时,它不会有任何选项吗?所以,它的M2M选项领域不会有任何东西。只有当用户选择添加该选项时才填充它。 –

+0

当你做newProject.options.add(* selectOptions)时,你不必要地用选项填充newProject,然后让用户删除不需要的,当它应该像让用户添加/删除任何他想要的。 –