建模的复杂关系在Django
-
20-08-2019 - |
题
我工作的一个网络服务在Django,我需要模型的一个非常具体的、复杂的关系,我只是能不能够解决的。
想想三种一般模式,让我们叫他们站点、职类和项目。每个网站含有一个或多个类别,但是它可能涉及到他们中的一两个可能的方式:一个是"共同的"类别,这是在一个"多对多"的关系:他们是预定的,而每个站点可以涉及到零或多个类别,反之亦然。其他类型的类别是单独定义为每个网站和一个这样的类别"所属"只有到那个网站没有其他人;即他们是在一个多对一关系,因为每个网站可以有一定数量的那些类别。
在内部,这两个类型的分类是完全相同,他们只能在不同的方式,他们是有关网站。它可以,但是,独立的,他们在两个不同的模型(带有一个共同的父模型可能的),但是,只解决了我一半的问题:该项目的模式是在多对一的关系的类别,即每个项目只属于一个类别,以及最理想的应该不在乎它如何是相关的网站。
另一种解决办法是允许两个单独类型的网站类关系共存(即有两个外键和ManyToMany场上相同的类型),但这种解决方案感觉就像整体的开口其他可能的蠕虫。
任何人都不会有一个主意,如果有一个第三,更好地解决这个死结束了吗?
解决方案
为什么不只是有两种类别的一个模型,所以你只要有3种型号?
Site
Category
Sites = models.ManyToManyField(Site)
IsCommon = models.BooleanField()
Item
Category = models.ForeignKey(Category)
您说“在内部,这两个类型的分类的完全一致”。所以听起来就像这是可能的。注意:这是完全可行的ManyToManyField有只有一个值,所以你并不需要“ForeignKey的和多对多场在同类型模型”,它只是听起来像一个麻烦。只要把只有一个值在多对多字段
其他提示
由于作为替代实现,你可以使用Django的内容类型(一般的关系)来完成项目的连接。一种使用这种实现的好处是,它可以让你利用不同的方式分类模型取决于您的数据需要在道路上。
您可以使用该网站的类别更容易通过编写模型方法来拉动和分类类别。 Django的contrib请管理员还支持通用的关系内联。
您的模型将如下:
Site(models.Model):
label = models.CharField(max_length=255)
Category(models.Model):
site = models.ManyToManyField(Site)
label = models.CharField(max_length=255)
SiteCategory(models.Model):
site = models.ForeignKey(Site)
label = models.CharField(max_length=255)
Item(models.Model):
label = models.CharField(max_length=255)
content_type = models.ForeignKey(ContentType)
object_id = models.PositiveIntegerField()
content_object = generic.GenericForeignKey('content_type', 'object_id')
有关内容类型的更深入的审查和如何查询通用的关系,你可以在这里阅读:的 HTTP://文档。 djangoproject.com/en/dev/ref/contrib/contenttypes/
警告:我知道对象的关系映射、轨道,蟒蛇,但不Django具体的说明。
我看到两个附加选项:
- 思维从一个数据库的观点,我可以使表格所需要的许多多的有关举行一个额外的领域,这表示一个"共同的"与"现场"的关系,并添加的限制类型的限制"的网站"的关系。这可以在决,我认为,在部分 "额外的领域在多对多关系。"
如果你是在一个较早的版本的强哥,你仍然可以这样做,使众多表示explict模型。
思维从一个对象的观点看,我可以看到分裂分类为三类:
BaseCategory
CommonCategory(BaseCategory)
SiteCategory(BaseCategory)
然后使用的一个决的继承模式。