如何简化Django模型中的复杂多对多关系

时间:2019-01-17 13:37:33

标签: python django-models relational-database

我已经搜索了一段时间,但是似乎找不到涵盖该问题的现有问题,或者我错过了寻找它的术语。

我正在尝试捕获与以下Django模型中的水果销售商示例类似的关系。

  • 卖方A在伦敦,柏林和巴黎出售苹果,梨和香蕉
  • 卖方B在伦敦出售苹果,梨和香蕉,但在柏林仅出售梨和在巴黎的香蕉
  • 卖方C在巴黎只出售苹果和香蕉

此刻我所拥有的是这样的:

class City(models.Model):
   name =  models.CharField(max_length=200)

class Region(models.Model):
   name =  models.CharField(max_length=200)
   cities = models.ManyToManyField(City)

class Fruit(models.Model):
   name =  models.CharField(max_length=200)

class Coverage(models.Model):
   name = models.CharField(max_length=200)
   regions = models.ManyToManyField(Region)
   fruits = models.ManyToManyField(Fruit)

class FruitSeller(models.Model):
   name = models.CharField(max_length=200)
   coverage = models.ManyToManyField(Coverage)

这可以工作,但是ManyToMany的所有字段都使它感觉不必要地复杂且不太优雅。最终,我需要查询“伦敦谁卖苹果”,“香蕉在哪里卖”,“卖方A卖什么水果”之类的东西。

我还考虑过添加另一种“市场”模型,该模型可以为水果贩,区域和水果提供外键,这将使Market.filter(Region__name='Western Europe', fruit__name='Apple').values('FruitSeller__name')之类的事情变得简单得多,但我认为可以通过管理页面添加新的水果卖家我认为我需要分别添加每个关系,这有点乏味。

最好的方法是什么?

1 个答案:

答案 0 :(得分:0)

我发现一个超级有用的小宝石是使用带有属性装饰器的外键集。这可能适合您。例如。

class City(models.Model):
   name =  models.CharField(max_length=200)

   # We add a property for the regions 
   @property
   def regions(self):
       # now we use the region set 
       return self.region_set.all()

class Region(models.Model):
   name =  models.CharField(max_length=200)
   city = models.ForeignKey(City)

您现在可以通过外键访问某个区域的城市,并且可以通过regions属性(city.regions)访问该城市的区域