我試圖對現有應用程序執行django-south migration以將django-audit-log添加到它(以跟蹤用戶啓動的模塊更改),但遇到了重大錯誤。特別是使用LastUserField(存儲指定正在跟蹤的更改的用戶)的action_user_id字段。django-south with django-audit-log
如果我從空白模型開始,我可以通過添加一個AUDIT_LOG:
from audit_log.models.managers import AuditLog
...
class SomeModel(models.Model)
...
audit_log = AuditLog()
運用這一簡單的變化,並在Django南做了schemamigration會心給我一個錯誤:
! Cannot freeze field 'myapp.mymodelauditlogentry.action_user'
! (this field has class audit_log.models.fields.LastUserField)
! South cannot introspect some fields; this is probably because they are custom
! fields. If they worked in 0.6 or below, this is because we have removed the
! models parser (it often broke things).
! To fix this, read http://south.aeracode.org/wiki/MyFieldsDontWork
我讀了MyFieldsDontWork wiki(和Custom Fields/Introspection部分),但它並沒有100%清楚我需要做些什麼才能使這些字段正常工作。
我嘗試添加:
from south.modelsinspector import add_introspection_rules
add_introspection_rules([], ["^audit_log\.models\.fields\.LastUserField"])
我的models.py其允許./manage.py schemamigration與以前的錯誤消失創建一個遷移腳本。然而,當我嘗試遷移(應用的遷移),我收到以下錯誤:
Running migrations for myapp:
- Migrating forwards to 0004_auto__add_mymodelauditlogentry.
> my_app:0004_auto__add_mymodelauditlogentry
Traceback (most recent call last):
File "./manage.py", line 11, in <module>
execute_manager(settings)
File "/usr/local/lib/python2.6/dist-packages/Django-1.2.3-py2.6.egg/django/core/management/__init__.py", line 438, in execute_manager
utility.execute()
File "/usr/local/lib/python2.6/dist-packages/Django-1.2.3-py2.6.egg/django/core/management/__init__.py", line 379, in execute
self.fetch_command(subcommand).run_from_argv(self.argv)
File "/usr/local/lib/python2.6/dist-packages/Django-1.2.3-py2.6.egg/django/core/management/base.py", line 191, in run_from_argv
self.execute(*args, **options.__dict__)
File "/usr/local/lib/python2.6/dist-packages/Django-1.2.3-py2.6.egg/django/core/management/base.py", line 220, in execute
output = self.handle(*args, **options)
File "/usr/local/lib/python2.6/dist-packages/South-0.7.3-py2.6.egg/south/management/commands/migrate.py", line 105, in handle
ignore_ghosts = ignore_ghosts,
File "/usr/local/lib/python2.6/dist-packages/South-0.7.3-py2.6.egg/south/migration/__init__.py", line 191, in migrate_app
success = migrator.migrate_many(target, workplan, database)
File "/usr/local/lib/python2.6/dist-packages/South-0.7.3-py2.6.egg/south/migration/migrators.py", line 221, in migrate_many
result = migrator.__class__.migrate_many(migrator, target, migrations, database)
File "/usr/local/lib/python2.6/dist-packages/South-0.7.3-py2.6.egg/south/migration/migrators.py", line 292, in migrate_many
result = self.migrate(migration, database)
File "/usr/local/lib/python2.6/dist-packages/South-0.7.3-py2.6.egg/south/migration/migrators.py", line 125, in migrate
result = self.run(migration)
File "/usr/local/lib/python2.6/dist-packages/South-0.7.3-py2.6.egg/south/migration/migrators.py", line 93, in run
south.db.db.current_orm = self.orm(migration)
File "/usr/local/lib/python2.6/dist-packages/South-0.7.3-py2.6.egg/south/migration/migrators.py", line 246, in orm
return migration.orm()
File "/usr/local/lib/python2.6/dist-packages/South-0.7.3-py2.6.egg/south/utils.py", line 62, in method
value = function(self)
File "/usr/local/lib/python2.6/dist-packages/South-0.7.3-py2.6.egg/south/migration/base.py", line 422, in orm
return FakeORM(self.migration_class(), self.app_label())
File "/usr/local/lib/python2.6/dist-packages/South-0.7.3-py2.6.egg/south/orm.py", line 46, in FakeORM
_orm_cache[args] = _FakeORM(*args)
File "/usr/local/lib/python2.6/dist-packages/South-0.7.3-py2.6.egg/south/orm.py", line 125, in __init__
self.models[name] = self.make_model(app_label, model_name, data)
File "/usr/local/lib/python2.6/dist-packages/South-0.7.3-py2.6.egg/south/orm.py", line 318, in make_model
field = self.eval_in_context(code, app, extra_imports)
File "/usr/local/lib/python2.6/dist-packages/South-0.7.3-py2.6.egg/south/orm.py", line 236, in eval_in_context
return eval(code, globals(), fake_locals)
File "<string>", line 1, in <module>
File "/usr/local/lib/python2.6/dist-packages/django_audit_log-0.2.1-py2.6.egg/audit_log/models/fields.py", line 12, in __init__
super(LastUserField, self).__init__(User, null = True, **kwargs)
TypeError: __init__() got multiple values for keyword argument 'null'
EDIT(12/20中午):我可以將schemamigration如果我添加了線的models.py
from south.modelsinspector import add_introspection_rules, add_ignored_fields
add_ignored_fields(["^audit_log\.models\.fields\.LastUserField"])
除了那麼AUDIT_LOG中間件不起作用,因爲在myapp_mymodelauditlogentry引用「AUTH_USER」的「ID」不action_user_id整型字段。然後我手動應用的SQL(SQLite的語法;通過使用新創建的數據庫上獲得sqliteman)
ALTER TABLE "myapp_mymodelauditlogentry" ADD "action_user_id" integer REFERENCES "auth_user" ("id");
和它的作品。如果有人解釋我應該如何在遷移/自省的django-south的背景下做到這一點,而不必依賴原始的依賴於數據庫的SQL並且很感激,我仍然會給予賞金。
另外,我爲action_user_id創建了一個索引。我注意到,在正常的創建模式與導致的指數稱爲
CREATE INDEX "myapp_mymodelauditlogentry_26679921" ON "myapp_mymodelauditlogentry" ("action_user_id")
我追殺的哈希26679921基於字段名創建了'%x' % (abs(hash(('action_user_id',))) % 4294967296L,)
而不是基於任何東西(所以應始終_26679921除非數據庫要求長名稱被截斷)。我不確定索引的名稱是否重要;但想要安全。
問題是南方不知道如何遷移你的領域。對於自定義字段,需要添加自己的內省規則,告訴南方哪些參數很重要,哪些參數可以忽略。如果我今晚有時間,我會寫一個關於如何使內省工作正常的例子。 – Wolph 2010-12-20 17:30:17
@WoLpH:是的,讓內省工作是問題,但在那裏幸運的是內省的文件。我不清楚,我是模式遷移/ django-south(以及django-audit-log)的新手。我嘗試的前幾件事不是用LastUserField工作的。如果你能夠進行自省工作(所以我不需要手動注入SQL),我會很感激,但說實話,我停止嘗試自己並轉移到其他問題上。 – 2010-12-22 21:54:10
我一直很忙,所以我沒有時間給你一個正確的答案。請忍耐一會兒:)(或其他人可以解釋它)。長話短說,它不起作用,因爲你沒有告訴南方有關參數,所以它忽略了它導致它通過兩次。 – Wolph 2010-12-23 01:09:02