21

私はモデルを持っています

class Category(models.Model):
    title           = models.CharField(...)
    entry           = models.ManyToManyField(Entry,null=True,blank=True,
                                             related_name='category_entries',
                                             )

各関係で追加のデータを取得するためにリファクタリングしたいこと:

class Category(models.Model):
    title           = models.CharField(...)
    entry           = models.ManyToManyField(Entry,null=True,blank=True,
                                             related_name='category_entries',
                                             through='CategoryEntry',
                                             )

しかし、south は既存のテーブルを削除します。既存の mtm 関係を維持するにはどうすればよいですか?

4

4 に答える 4

23
  1. 今のところ、追加のフィールドを使用せずに中間モデルを作成します。既存のものと一致するように一意の制約を与え、既存のものと一致するようにテーブル名を指定します。

    class CategoryEntry(models.Model):
        category = models.ForeignKey(Category)
        entry = models.ForeignKey(Entry)   
    
        class Meta:
            db_table='main_category_entries'   #change main_ to your application
            unique_together = (('category', 'entry'))
    
  2. South スキーマの移行を実行します。

  3. 既存の交差テーブルを再利用するため、生成されたスキーマ移行スクリプトを編集し、前方および後方エントリをすべてコメントアウトします。追加passしてメソッドを完成させます。

  4. 移行を実行します。

  5. 既存のコードを更新します。https://docs.djangoproject.com/en/dev/topics/db/models/#many-to-many-relationshipsにあるように、「通常の多対多フィールドとは異なり、add は使用できません。 create、または割り当てを作成して関係を作成する」ため、既存のアプリケーション コードを変更する必要があります。

    c.entry.add(e)
    

    次のようになります。

    try:
        categoryentry = c.categoryentry_set.get(entry = e)
    except CategoryEntry.DoesNotExist:
        categoryentry = CategoryEntry(category=c, entry=e)
        categoryentry.save()
    

    と:

    e.category_entries.add(c)
    

    次のようになります。

    categoryentry = CategoryEntry(category=c, entry=e)  #set extra fields here
    categoryentry.save()                
    

    と:

    c.entry.remove(e)
    

    次のようになります。

    categoryentry = c.categoryentry_set.get(entry = e)
    categoryentry.delete()
    
  6. この最初の疑似移行が完了すると、追加のフィールドを に追加し、CategoryEntry通常どおりさらに移行を作成できるようになります。

于 2012-08-16T11:24:29.680 に答える
4

私は次のようにします:

  1. クラスをモデルに追加し、CategoryEntryスキーマの自動移行を行います。これにより、 のプロパティを含む空のテーブルが追加されますCategoryEntry。注意すべきは、古い M2M テーブルがthrough='CategoryEntry'まだ追加されていないため、変更されていないことです。

  2. データ移行を実行して、既存の M2M テーブルからステップ 1 で作成したテーブルにすべてのデータをコピーします。これを行うには、datamigrationコマンドを実行し、メソッドを編集forward()backward()、それに応じて自動生成された移行スクリプトを編集します。

  3. パーツを追加through='CategoryEntry'して (思い通りに)、スキーマ移行を実行します。これにより、古い M2M テーブルが削除されます。

于 2012-12-12T13:35:43.143 に答える