这个Django模型架构是否方便?

时间:2016-11-18 01:27:31

标签: django database-design

我们假设一个Bar可以是多个Zipcodes。

class State(models.Model):
    abbr = models.CharField(max_length=2)

class City(models.Model):
    state = models.ForeignKey(State, related_name='cities')
    name = models.CharField(max_length=120)

class Zipcode(models.Model):
    city = models.ForeignKey(City, related_name='zipcodes')
    value = models.CharField(max_length=5)

class Bar(models.Model):
    name = models.CharField(max_length=120)
    zipcodes = models.ManyToManyField(Zipcode, related_name='bars')
    # cities = models.ManyToManyField(City, related_name='bars')
    # states = models.ManyToManyField(State, related_name='bars')

用例#1

# Duff zipcodes
>>> bar = Bar.objects.get(name='Duff')
>>> bar.zipcodes.all()

而且,

# 98101 bars
>>> zipcode = Zipcode.objects.get(value='98101')
>>> zipcode.bars.all()

然后,如果我需要获得酒吧城市,我会做

# Duff cities
>>> City.objects.filter(zipcodes__bars=bar).distinct() # ouch?

或者可能是Bar的财产,

class Bar(models.Model):
    ...

    @property
    def cities(self):
        return City.objects.filter(zipcodes__bars=self).distinct()

>>> bar.cities.all()

添加"城市" Bar中的m2m确实是,

>>> bar.cities.all()

但是,如果我已经知道cities有拉链码,为什么在Bar中添加cities为m2m? 我需要保持两个m2m关系。

  • 即。如果向栏添加邮政编码,我可能需要将一个城市(与该邮政编码相关)添加到栏cities

  • 即。如果我从栏中删除了一个邮政编码,我可能需要从栏中cities删除一个城市(与该邮政编码相关)。

用例#2

我们想说我们想知道至少有一个条形码的所有拉链码,

>>> Zipcode.objects.filter(bars__isnull=False).distinct()

或至少有一个酒吧的城市,

>>> City.objects.filter(zipcodes__bars__isnull=False).distinct()

或至少有一个酒吧的州?,

>>> State.objects.filter(cities__zipcodes__bars__isnull=False).distinct()

我不确定这些查询是否有效且干净,或者是更好的方法。 也许我可以添加自定义管理器方法,例如,

>>> City.objects.with_bars() # = City.objects.filter(zipcodes__bars__isnull=False).distinct()

所以主要问题是,您认为模型架构关系是好还是方便?

1 个答案:

答案 0 :(得分:0)

是的,这看起来很好,就查询而言,我不认为会有很多深层嵌套,最多可能是3级。所以不要为此烦恼,我们多次试图预先优化。没问题,但现在还可以。