2016-06-22 14 views
3

私は複数のモデル(django 1.9)に分割しているdjangoモデルを持っています appは多かれ少なかれアイテムやアイテムのセットを追跡するシステムです通常はファイルに関連付けられます。モデルを複数のモデルに分割するためのdjangoの移行を作成する方法

class ItemTypeA(models.Model): 
    field1 = models.CharField(max_length=512) 
    ... 
    base_dir = models.CharField(max_length=512) 
    rel_fname = models.CharField(max_length=512) 
:ここ

にも関連するファイルを持っているアイテムの一つのおもちゃの例がある(私は使用して、ファイルのフィールドを行わない理由は、これらのファイルがアップロード、またはユーザーによって追加されていない、これはです)

そのモデルでは、フィールド1でフィルタリングしてから適切なファイルを取得できます(実際のモデルには多くのフィールドがあり、他のモデルとの関係はリストされていません)。さらに多くのタイプのアイテムがあります。

私はファイルの詳細をonetoone関係の別のモデルに移動したいと思います。

これは次のようになります。

class Filesystem(models.Model): 
    dirpath = models.CharField(max_length=512) 
    ... #Some other details for accessing the system, and system availablity. 

class BaseFile(models.Model): 
    filesystem = models.ForeignKey(Filesystem,related_name="system") 
    filepath = models.CharField(max_length=512) 
    md5 = models.CharField(max_length=16, editable=False) 
    md5_check_datetime = models.DateTimeField() 
    size = models.IntegerField(verbose_name="file_size") 
    class Meta: 
     abstract = True 

class ItemTypeAFile(BaseFile): 
    pass 

class ItemTypeA(models.Model): 
    field1 = models.CharField(max_length=512) 
    file = models.OneToOneField(ItemTypeAFile) 

私は、ファイルシステムがそれぞれのユニークなbase_dir==>dirpathのために作成され、新しいItemTypeAFileオブジェクトがOldItemTypeA.rel_fname==>ItemTypeAFile.filepathで作成されていることを、このようにの移行を作成したいと思います。

私はこれでどこから始めるのか本当に知りません。

答えて

3

southを使用して新しいモデルの移行を作成し、新しいクラスの新しいオブジェクトをコピー/作成して元のモデルからフィールドを削除することができます。 は、ここで私は何をすべきかです:

  1. は、新しいモデル(ItemFile)を作成し、
  2. は、標準的な方法
  3. 編集移行を使用して南の移行を生成ItemA
  4. からフィールドを削除し、ループを追加しないことすべてのItemAオブジェクトを通過し、必要なFilesystemオブジェクトとItemAFileオブジェクトを作成します。
  5. モデルからフィールドを削除し、別の移行を作成します。

ここでは、コードは(3)のように見えるかもしれませんために何:

def forwards_func(apps, schema_editor): 
    ItemA = apps.get_model("app", "ItemA") 
    Filesystem = apps.get_model("app", "Filesystem") 
    ItemAFile = apps.get_model("app", "ItemAFile") 

    for item in ItemA.objects.all(): 
     fs,added = Filesystem.objects.get_or_create(dirpath=str(item.base_dir)) 
     itemafile=ItemAFile(itema=item, filesystem=fs, filepath=item.rel_fname) 
     # do md5 stuff 
     .... 
     itemafile.save() 

def reverse_func(apps, schema_editor): 
    Filesystem = apps.get_model("app", "Filesystem") 
    ItemAFile = apps.get_model("app", "ItemAFile") 

    Filesystem.objects.all().delete() 
    ItemAFile.objects.all().delete() 

class Migration(migrations.Migration): 

    dependencies = [ 
     ... 
    ] 

    operations = [ 
     ... 
     migrations.RunPython(forwards_func, reverse_func), 
    ] 

私はItemAFileクラスではなく、ItemAクラスにonetooneを置くことを検討します:

class ItemTypeAFile(BaseFile): 
    item = models.OneToOneField(ItemTypeA) 

この方法では、 ItemAオブジェクトを削除すると、関連付けられたItemAFileオブジェクトも削除されます。 ItemAFileはItemAの拡張であるため、これは必要な動作である可能性があります。

関連する問題