2009-07-17 11 views
159

ユーザーへの2つのリンクを含むオブジェクトを作成したいとします。たとえば、次のようにDjango:なぜいくつかのモデルフィールドは互いに衝突しますか?

class GameClaim(models.Model): 
    target = models.ForeignKey(User) 
    claimer = models.ForeignKey(User) 
    isAccepted = models.BooleanField() 

が、サーバーを実行しているとき、私は次のエラーを取得しています:

  • アクセサ関連分野「User.gameclaim_set」がフィールド「ターゲット」の衝突のために。 'target'の定義にrelated_name引数を追加します。関連分野 'User.gameclaim_set' がフィールド '請求者' の衝突のための

  • アクセサ。 related_name引数を 'claimer'の定義に追加します。

は、私はエラーを取得し、それらをどのように修正することになっている理由を説明していただけますか?

+0

_Theseエラーメッセージが実際にある彼らはすでにそれらを修正する方法を説明しgood._:

[値のクラスの子供たちに、あなたはへのアクセス権を持っています。そして、ドキュメンテーションの** ['related_name' **(https://docs.djangoproject.com/en/dev/ref/models/fields/#arguments)を読んで、なぜそれが起こるのかを説明します。 –

答えて

277

ユーザーには2つの外部キーがあります。 DjangoはUserからGameClaimへの逆の関係を自動的に作成します。通常はgameclaim_setです。しかし、2つのFKがあるので、2つの属性を持つことになりますが、これは明らかに不可能です。したがって、逆の関係に使う名前をDjangoに伝える必要があります。

FK定義のrelated_name属性を使用します。例えば

class GameClaim(models.Model): 
    target = models.ForeignKey(User, related_name='gameclaim_targets') 
    claimer = models.ForeignKey(User, related_name='gameclaim_users') 
    isAccepted = models.BooleanField() 
+47

良い答えですが、私はあなたが無礼を避けることに成功したとは思わない:P「なぜ」は、あなたがジャンゴが内部的にどのように働いているのか分からない限り明白ではありません。 – Kenny

+12

フレームワークを勉強している人にとって、これは明らかではありません。 – jkyle

+2

ありがとう、エラーメッセージも私には分かりませんでしたが、逆の関係についてのあなたの説明はとても役に立ちました。 – ruquay

6

Userモデルは、同じ名前を持つ2つのフィールド、targetとしてUser、そしてclaimerとしてUserことがありGameClaimsための別のことをしていGameClaimsのための1つを作成しようとしています。 docs on related_nameは、自動生成されたものが競合しないように属性の名前を設定できるDjangoの方法です。

5

OPは抽象基本クラスを使用していない...しかし、あなたがしている場合は、そのハード(例えば...、related_name =「MYNAME」)となりますFKでrelated_nameコーディングいますこれらの競合エラーの数は、基本クラスから継承されたクラスごとに1つです。以下のリンクには回避策が含まれていますが、これは簡単ですが、はっきりとは分かりません。 Djangoのドキュメントから

...

あなたがのForeignKeyや のManyToManyFieldにrelated_name 属性を使用している場合は、常に フィールドの一意の逆の名前を指定する必要があります。このクラスのフィールドがまったく同じ値( related_name含む)属性の たびに、子供 の各クラスに 含まれているので、これは通常、抽象基底クラス、 で 問題を引き起こします。

詳細情報here

0

私は、たとえば次のような構造を考えると、私はDjangoプロジェクトへの応用として、サブモジュールを追加するときに、時折、この渡って来るように見える:私はINSTALLED_APPSに以下を追加した場合

myapp/ 
myapp/module/ 
myapp/module/models.py 

を:

'myapp', 
'myapp.module', 

Djangoはmyapp.mymodule models.pyファイルを2回処理して上記のエラーをスローします。これはINSTALLED_APPSリストにあるメインモジュールを含めないことによって解決することができます。

myappの代わり myapp.moduleすべてのデータベーステーブルが正しくない名前で作成されますので、これを行うには正しい方法であるように思わ含め
'myapp.module', 

それ。

この問題への解決策を探している間、私はそうあなたがインポートする場合、それはまた起こることができるだけでヨルダンの答えに(先端ヨルダンへの感謝を)加える私はここにこれを置くと思います:)

0

を考え出しこの記事に出くわしましたアプリケーションのレベルを上げ、アプリケーションをインポートする

myproject/ apps/ foo_app/ bar_app/

あなたがアプリケーション、foo_appとbar_appをインポートしているのであれば、あなたはこの問題を得ることができます。その後、あなたは2つの異なる名前空間

apps.foo_appfoo_app

-2
にインストールしたのと同じアプリを持っているので、私は、すべてのsettings.INSTALLED_APPS

に記載されているそして、あなたはとにかくアプリケーションをインポートしないようにしたいアプリ、foo_appとbar_appを持っていました

私は同じ問題を抱えていました。私はpython manage.py makemigrations "appname"を実行して固定しました。私はいくつかの移行ファイルを誤って削除した。ファイルを再削除する必要はありません。

0

related_name では、実際には継承が使用されているときにいつも特別なフォーマットを使用する必要があります。

class Value(models.Model): 
    value = models.DecimalField(decimal_places=2, max_digits=5) 
    animal = models.ForeignKey(
     Animal, related_name="%(app_label)s_%(class)s_related") 

    class Meta: 
     abstract = True 

class Height(Value): 
    pass 

class Weigth(Value): 
    pass 

class Length(Value): 
    pass 

ここではクラッシュはありませんが、related_nameは一度定義されており、Djangoは一意のリレーション名を作成します。

herdboard_height_related 
herdboard_lenght_related 
herdboard_weight_related 
関連する問題