简体   繁体   中英

How can I simplify complex many-to-many relationships in Django models

I've searched around for a while, but can't seem to find an existing question that covers this or I'm missing the terminology to find it.

I'm trying to capture a relationship similar to the following example of fruit sellers in Django models.

  • Seller A sells Apples, Pears and Bananas in London, Berlin and Paris
  • Seller B sells Apples, Pears and Bananas in London but only Pears in Berlin and Bananas in Paris
  • Seller C sells only Apples and Bananas in Paris

What I have at the moment looks like this:

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)

This works but all the ManyToMany fields make it feel unnecessarily complex and not very elegant. Ultimately I need to be able to query things like 'Who sells Apples in London' 'Where are Bananas sold', 'What fruit does Seller A sell'.

I've also considered adding another model 'Market' which foreign keys to fruitseller, region and fruit which would allow things like Market.filter(Region__name='Western Europe', fruit__name='Apple').values('FruitSeller__name') That feels much simpler but I think makes adding new fruit sellers via the admin page a bit of a tedious exercise as I believe I would need to add each relationship individually.

What is the best approach to this?

A little gem I find super usefule is using foreign key sets with a property decorator. This might work well for you. For example.

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)

You can now access the city of a region through its foreign key, and you can access the regions of a city through the regions property (city.regions)

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM