2013-06-25 26 views
1

假設你正在開發一個Django項目,有幾個人使用(例如)git。當你做git pull你可能會得到一些南遷,但是,你可能沒有注意到(出於某種原因)。然後當你繼續開發時,你可能會遇到python異常,因爲你沒有進行遷移。現在有時可能會有一段時間,然後才發現你忘記了這一點,這很煩人。Django South - 任何方式來檢測是否需要進行南遷移?

因此,我想,南方不能檢測到你沒有完成所有的遷移,只是拋出異常,如果是這樣?

我imagen這可能是一個設置,你可以關閉,如果你想繼續發展而不進行遷移。

+0

我居然發現,介紹瞭如何以編程方式檢測是否有向南遷移到運行文章來源(http://rochacbruno.com.br/programatically-check-如果 - 你 - 南有-遷移到運行/)。我可能會將其轉換爲我將添加到開發設置中的中間件。我會回答自己的問題,如果我設法這樣做。 – rednaw

回答

1

好吧,我做了一些中間件,做我想做的。當您執行請求時,它會檢查您尚未應用的遷移並引發異常。一定要在開發中使用這個中間件!

您也可以找到關於https://gist.github.com/gitaarik/5974176

from south import migration 
from south.models import MigrationHistory 


class SouthUnranMigrationCheck(object): 

    def process_request(self, request): 
     ''' 
     Checks if you ran all South migrations. If not, it will throw an 
     exception (DidNotApplyAllMigrations). 
     ''' 

     unapplied_migrations = self.unapplied_migrations() 

     if len(unapplied_migrations) > 0: 

      message = u'You haven\'t run the following migrations: {}'.format(
       u''.join(
        [u'\n "{}" in app "{}".'.format(name, app) 
        for name, app in unapplied_migrations] 
       ) 
      ) 

      raise DidNotApplyAllMigrations(message) 

    def unapplied_migrations(self): 
     ''' 
     Returns a list of tuples of unapplied migrations. The tuples consist of 
     a migration name and an app label. 
     ''' 

     applied_migrations = self.applied_migrations() 
     unapplied_migrations = [] 

     for app_migration_files in migration.all_migrations(): 

      for migration_file in app_migration_files: 

       app_label = migration_file.app_label() 
       migration_name = migration_file.name() 

       if migration_name not in applied_migrations[app_label]: 
        unapplied_migrations.append((migration_name, app_label)) 

     return unapplied_migrations 

    def applied_migrations(self): 
     ''' 
     Returns a dictionary with the app name in the key, and a list of 
     migrations in the value. 
     ''' 

     applied_migrations = {} 

     for applied_migration in MigrationHistory.objects.all(): 

      if applied_migration.app_name not in applied_migrations: 
       applied_migrations[applied_migration.app_name] = [] 

      applied_migrations[applied_migration.app_name].append(
       applied_migration.migration) 

     return applied_migrations 


class DidNotApplyAllMigrations(Exception): 
    ''' 
    Exception that indicates that you havent run all migrations. 
    ''' 
    pass 
+1

什麼?爲什麼downvote?請解釋。 – rednaw

3

好的,這是我的方式。

我有一個應用程序south_test 3遷移,這就是'python manage.py遷移--list'顯示:

south_test 
    (*) 0001_initial 
    (*) 0002_auto__add_person 
    () 0003_auto__add_field_person_age 

即(不要太)魔碼:

from south.models import MigrationHistory 
from south.migration import Migrations 

all_migrations = Migrations('south_test') 
applied_migrations = MigrationHistory.objects.filter(app_name='south_test') 

not_applied = list(set(all_migrations) - set([migration.get_migration() for migration in applied_migrations])) 

現在您有not_applied遷移。 也許有一些關於鬼遷移的細節。

詳情請參閱南方的migrate指令。

希望這會有所幫助!

+0

謝謝你。最終我創建了我自己的中間件來解決我的問題。檢查我的答案。 – rednaw