Is this Django model schema convenient?
<p>Let's say a Bar can be in multiple Zipcodes.</p>

<pre><code>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')
</code></pre>

<h2>Use case #1</h2>

<pre><code># Duff zipcodes
&gt;&gt;&gt; bar = Bar.objects.get(name='Duff')
&gt;&gt;&gt; bar.zipcodes.all()
</code></pre>

<p>And also,</p>

<pre><code># 98101 bars
&gt;&gt;&gt; zipcode = Zipcode.objects.get(value='98101')
&gt;&gt;&gt; zipcode.bars.all()
</code></pre>

<p>Then, if I need to get the bar cities I would do</p>

<pre><code># Duff cities
&gt;&gt;&gt; City.objects.filter(zipcodes__bars=bar).distinct() # ouch?
</code></pre>

<p>or maybe a property in Bar,</p>

<pre><code>class Bar(models.Model):
    ...

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

&gt;&gt;&gt; bar.cities.all()
</code></pre>

<p>Adding "cities" m2m in Bar would really be,</p>

<pre><code>&gt;&gt;&gt; bar.cities.all()
</code></pre>

<p>However, why adding <code>cities</code> as m2m in Bar, if I already know the <code>cities</code> having the zipcodes?
I would need to mantain both m2m relationships.</p>

<ul>
<li><p>i.e. If add a zipcode to a bar, I may have to add a city (related to that zipcode) to the bar <code>cities</code>.</p></li>
<li><p>i.e. If I remove a zipcode from a bar, I may have to remove a city (related to that zipcode) from bar's <code>cities</code>.</p></li>
</ul>

<h2>Use case #2</h2>

<p>Let's say we want to know all the zipcodes that have at least a bar,</p>

<pre><code>&gt;&gt;&gt; Zipcode.objects.filter(bars__isnull=False).distinct()
</code></pre>

<p>Or the cities that have at least a bar,</p>

<pre><code>&gt;&gt;&gt; City.objects.filter(zipcodes__bars__isnull=False).distinct()
</code></pre>

<p>Or the states that have at least a bar?,</p>

<pre><code>&gt;&gt;&gt; State.objects.filter(cities__zipcodes__bars__isnull=False).distinct()
</code></pre>

<p>I'm not sure if those queries are efficent and clean or is a better way to make them.
Maybe I could add custom Manager methods, so for example,</p>

<pre><code>&gt;&gt;&gt; City.objects.with_bars() # = City.objects.filter(zipcodes__bars__isnull=False).distinct()
</code></pre>

<p>So the main question is, do you think the Model schema relationships is good/convenient?</p>