2011-05-23 4 views
9

私はM2M分野でのユーザープロファイルのモデルを持っているのManyToManyFieldと南の移行

class Account(models.Model): 
    ... 
    friends = models.ManyToManyField('self', symmetrical=True, blank=True) 
    ... 

今私は知っている方法と時期FRIEND としてお互いを追加する必要があると私はその

class Account(models.Model): 
    ... 
    friends = models.ManyToManyField('self', symmetrical=False, blank=True, through="Relationship") 
    ... 


class Relationship(models.Model):  
    """ Friends """   
    from_account = models.ForeignKey(Account, related_name="relationship_set_from_account")    
    to_account = models.ForeignKey(Account, related_name="relationship_set_to_account") 
    # ... some special fields for friends relationship 

    class Meta:      
     db_table = "accounts_account_friends"    
     unique_together = ('from_account','to_account') 
するためのモデルを作成しました

この変更のために移行を作成する必要がありますか? ご意見がありましたら、気軽にここにお書きください。

おかげ

PS:accounts_account表がすでに含まれていたレコード

答えて

8

最初に、可能であればdb_tableエイリアスを使用しないでください。これは、モデルと同期していないため、テーブル構造を理解するのが難しくなります。

第2に、South APIは、db.rename_table()のような機能を提供します。この機能は、手動で移行ファイルを編集することによって使用できます。 accounts_account_friendsテーブルの名前をaccounts_relationに変更し(Djangoはデフォルトで名前を付けます)、追加の列を追加することができます。ユニークな関係が除去され、制約が適切な名前を持つように再作成され

def forwards(self, orm): 
    # the Account.friends field is a many-to-many field which got a through= option now. 
    # Instead of dropping+creating the table (or aliasing in Django), 
    # rename it, and add the required columns. 

    # Rename table 
    db.delete_unique('accounts_account_friends', ['from_account', 'to_account']) 
    db.rename_table('accounts_account_friends', 'accounts_relationship') 

    # Add extra fields 
    db.add_column('accounts_relationship', 'some_field', ...) 

    # Restore unique constraint 
    db.create_unique('accounts_relationship', ['from_account', 'to_account']) 


def backwards(self, orm): 

    # Delete columns 
    db.delete_column('accounts_relationship', 'some_field') 
    db.delete_unique('accounts_relationship', ['from_account', 'to_account']) 

    # Rename table 
    db.rename_table('accounts_relationship', 'accounts_account_friends') 
    db.create_unique('accounts_account_friends', ['from_account', 'to_account']) 


models = { 
    # Copy this from the final-migration.py file, see below 
} 

:これは組み合わせ

はあなたの次の移行を提供します。

  • まだ外部キーフィールドのみ、およびM2Mフィールドを変更することなくmodels.pyRelationshipモデルを追加します。

    列ステートメントを追加は簡単に以下のトリックで生成されます。

  • フィールドをRelationshipモデルに追加します。
  • Do a ./manage.py schemamigration app --auto --stdout | tee final-migration.py | grep column
  • 最初の移行を元に戻します。

次に、移行ファイルを作成するために必要なものがすべて用意されています。

+0

お返事ありがとうございます – srusskih

+0

@srussskih:聞いて嬉しいです! – vdboor

1

それはそこにコード化されたあなたが持っている方法は、手動でM2Mと同じ仕事はそのDjangoは意志のテーブルに参加したモデルを定義していますあなたのために自動的に作成されます。事は、自動的に作成されたテーブルはaccounts_relationship_friendと呼ばれます。

ORMがサーフェスの下で行ったことを複製しようとするモデルが作成されますが、間違ったテーブルを指しています。

明示的な結合モデルが必要ない場合は、コードベースから削除して、追加するための移行を作成せず、代わりにM2Mを使用して友人間の関係を検索します。 (私はこれについて深く考えていませんが、うまくいくはずです)。

ただし、あなたが持っているリレーションシップモデル(リレーションシップの種類などのストア属性など)に特別なことをしたい場合は、リレーションシップモデルをあなたのフレンドで使用するスルーモデルに宣言します。友達m2mの定義。 See the docs here.

+0

私はm2mフィールド 'friends'を持つモデルを持っており、DBにプロファイルがあります。リレーションシップ(作成日など)に特別なプロパティを追加します。そして、私はトラフテーブルを作成します。そして私は知りたいと思う:私はこのケースのために移行を行うかどうか。 答えは良い情報が含まれていますが、私はすでにこれを行っています。 – srusskih

関連する問題