2009-04-28 11 views
5

私はmodels.py宣言の順序はmodels.py(Django/Python)で重要ですか?私は私が手にこれを行うと

class ZipCode(models.Model): 
    zip = models.CharField(max_length=20) 
    cities = City.objects.filter(zip=self).distinct() 

class City(models.Model): 
    name = models.CharField(max_length=50) 
    slug = models.CharField(max_length=50) 
    state = models.ForeignKey(State) 
    zip = models.ManyToManyField(ZipCode) 

でこのようなものを持っている:

NameError: name 'City' is not defined 

は、これは、宣言の順序が重要?もしそうなら、私はどのようにこれを行うことができます。いずれにしても、私はこれを整理するので、NameErrorを取得するように見えます。

ありがとうございました。

答えて

2

はい、他の人の注目するとおりです。

この問題に遭遇しても、ほとんどの場合、間違ったことをしていることがわかります。この場合

あなたの宣言:

cities = City.objects.filter(zip=self).distinct() 

... redundantと悪い習慣の両方があります。ビュー内でその郵便番号のcity_setを参照することで、郵便番号に関連する都市を見つけることができます(つまり、モデルにはありません)。ジッパーは、郵便番号のインスタンスであれば、あなたはどうなる:

cities = zip.city_set.all() 

あなたが本当にあなたのM2M宣言でrelated_nameパラメータを使用することができ、むしろ「city_set」より「都市のそれを呼び出すようにしたい場合。

0

Pythonでの問題を整理します。 This threadがあなたの質問に関連している可能性があります。また、あなたの使用のために、ZIPコードクラスで一意の外部キーを使用することができます。

2

はい、注文は問題ありませんが、あなたの例は私には見えません。 Djangoのモデルと多対一の関係上

cities = models.ForeignKey(City) 

This has the details:私は、あなたは自分の多対1の関係の外部キーを使用してされるべきだと思います。

編集:

それは、ヨーロッパの都市が同じ郵便番号でのいくつかの都市があるかもしれないコメントで私に指摘されました。あなたはここで多対多の関係を探しているなら、あなたが使用する必要があります。

cities = models.ManyToManyField(City) 

これはDjango's documentationに記載されています。要点は、これはこれらの例のいずれかが例で使用されているものよりはるかに明確であることです。

+1

こんにちはシェーン、あなたの提案は、郵便番号が1つの都市にのみ関連付けることができますが、郵便番号は複数の都市に属することができ、1つの都市には複数の郵便番号があると考えています。そうじゃないの? – rick

+0

いいえ、多対1の関係を持つことができますが、ここで使用した構文には慣れていません。私が上で提供したリンクによると、 "多対1の関係を定義するには、ForeignKey()を使用してください" –

+0

多対多と多対多の2つの異なる関係、シェーンです。このケースでは、おそらく単一の郵便番号として多対多が複数の都市を表す場合があります(国際的に考える)。それはポイントのほかにもあります。双方向のバイナリ関係を宣言することは悪い考えであり、冗長です。 – ozan

5

あなたは後に定義されたクラスへの参照を持っている場合、あなたはこのトリックを使用することができます。

attribute = models.ForeignKey('ClassDefinedAfterThis') 
+0

これは動作しますか? cities = 'City'.objects.filter(zip = self).distinct() – rick

+0

その時点での位置は重要ではありません – phillc

+2

@rick:いいえ、動作しません。 –

3

私は以下の私のモデルは唯一の参照モデルは、上記と考えていたので、私は...一度オーダーを心配していました。しかし、あなたができることが分かりました

models.ForeignKey('appName.modelName') 

すべてが問題ありませんでした。

+0

それは..... – alexvassel

6

別にオーダーの問題から、これは間違っている:

cities = City.objects.filter(zip=self).distinct() 

それはメソッドの内部ではないので、「自己」も定義されません。これは、クラス作成時(すなわち、モジュールが最初にインポートされるとき)に1回だけ実行されるので、作成される属性はクラス属性であり、すべてのインスタンスに対して同じ値を持ちます。あなたが探しているかもしれないことはこれです:

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

それがアクセスされるまで、これが実行されていない方法で、内部にあるので、発注の問題は、もはや問題ではないだろう。

a_zip_code.city_set.all() 
をそして、あなたはあなたが好きなもの、それを呼び出すためにrelated_nameを使用することができます:

zip = models.ManyToManyField(ZipCode, related_name='cities') 
... 
a_zip_code.cities.all() 

だから私は「ドンオザンが指摘するように、これは、Djangoはすでに自由のためにあなたを与える関係を逆に何の重複であります元々あなたが尋ねた発注問題は、あなたの状況にも関係していると思います。そうであれば、他の人は、ForeignKeyとManyToManyField宣言で引用符で囲まれた文字列を使用してそれを回避することを既に指摘しています。

関連する問題