1

私は南に不慣れで、彼らのドキュメントに従い、南への移行を初期化した後、実行した後

manage.py migrate appname

次のカスタムモデルの場合モデル私は次のようにイントロスペクションルールを追加しました

モデル:

class DependentIntegerField(models.IntegerField):

     def __init__(self, default_callable, *args, **kwargs):
          self.default_callable = default_callable
          super(DependentIntegerField, self).__init__(*args, **kwargs)

     def pre_save(self, model_instance, add):
          if not add:
               return super(DependentIntegerField, self).pre_save(model_instance, add)

          return self.default_callable(model_instance)

class Level(models.Model):
     group = models.ForeignKey(Level_Group)
     number = models.IntegerField(unique=True)#null=True, blank=True
     threshold = DependentIntegerField(lambda mi:mi.number*50,null=False,blank=True)

     def __str__(self):
          return '%s' %(self.number)

     def get_fib(self):
          return fib(self.number+3)

class Gallery (models.Model):
     contractor = models.ForeignKey(Contractor)
     image = StdImageField(upload_to='GalleryDB', size=(640, 480,True))
     Title = models.CharField(max_length=250,null=True,blank = True)
     Caption = models.CharField(max_length=1000,null=True,blank=True)

イントロスペクションルール:

add_introspection_rules([
    (
        [Level], # Class(es) these apply to
        [],         # Positional arguments (not used)
        {           # Keyword argument
            "threshold": ["threshold", {}],
        },
    ),
], ["^shoghlanah\.models\.DependentIntegerField"])

add_introspection_rules([
    (
        [Gallery], # Class(es) these apply to
        [],         # Positional arguments (not used)
        {           # Keyword argument
            "image": ["image"], "upload_to": ["GalleryDB"]
        },
    ),
], ["^stdimage\.fields\.StdImageField"])

トレースバック

Traceback (most recent call last):
  File "manage.py", line 10, in <module>
    execute_from_command_line(sys.argv)
  File "/Library/Python/2.7/site-packages/django/core/management/__init__.py", line 443, in execute_from_command_line
    utility.execute()
  File "/Library/Python/2.7/site-packages/django/core/management/__init__.py", line 382, in execute
    self.fetch_command(subcommand).run_from_argv(self.argv)
  File "/Library/Python/2.7/site-packages/django/core/management/base.py", line 196, in run_from_argv
    self.execute(*args, **options.__dict__)
  File "/Library/Python/2.7/site-packages/django/core/management/base.py", line 232, in execute
    output = self.handle(*args, **options)
  File "/Library/Python/2.7/site-packages/South-0.7.5-py2.7.egg/south/management/commands/migrate.py", line 107, in handle
    ignore_ghosts = ignore_ghosts,
  File "/Library/Python/2.7/site-packages/South-0.7.5-py2.7.egg/south/migration/__init__.py", line 219, in migrate_app
    success = migrator.migrate_many(target, workplan, database)
  File "/Library/Python/2.7/site-packages/South-0.7.5-py2.7.egg/south/migration/migrators.py", line 235, in migrate_many
    result = migrator.__class__.migrate_many(migrator, target, migrations, database)
  File "/Library/Python/2.7/site-packages/South-0.7.5-py2.7.egg/south/migration/migrators.py", line 310, in migrate_many
    result = self.migrate(migration, database)
  File "/Library/Python/2.7/site-packages/South-0.7.5-py2.7.egg/south/migration/migrators.py", line 133, in migrate
    result = self.run(migration)
  File "/Library/Python/2.7/site-packages/South-0.7.5-py2.7.egg/south/migration/migrators.py", line 99, in run
    south.db.db.current_orm = self.orm(migration)
  File "/Library/Python/2.7/site-packages/South-0.7.5-py2.7.egg/south/migration/migrators.py", line 260, in orm
    return migration.orm()
  File "/Library/Python/2.7/site-packages/South-0.7.5-py2.7.egg/south/utils/__init__.py", line 62, in method
    value = function(self)
  File "/Library/Python/2.7/site-packages/South-0.7.5-py2.7.egg/south/migration/base.py", line 427, in orm
    return FakeORM(self.migration_class(), self.app_label())
  File "/Library/Python/2.7/site-packages/South-0.7.5-py2.7.egg/south/orm.py", line 45, in FakeORM
    _orm_cache[args] = _FakeORM(*args) 
  File "/Library/Python/2.7/site-packages/South-0.7.5-py2.7.egg/south/orm.py", line 124, in __init__
    self.models[name] = self.make_model(app_label, model_name, data)
  File "/Library/Python/2.7/site-packages/South-0.7.5-py2.7.egg/south/orm.py", line 317, in make_model
    field = self.eval_in_context(code, app, extra_imports)
  File "/Library/Python/2.7/site-packages/South-0.7.5-py2.7.egg/south/orm.py", line 235, in eval_in_context
    return eval(code, globals(), fake_locals)
  File "<string>", line 1, in <module>
TypeError: __init__() takes at least 2 arguments (1 given)

現場からのものかどうかはほとんどDependentIntegerFieldわかりませんが、どちら__init__に電話をかけようとしているのかわかりません。

"threshold": ["threshold", {"ldefault_callable":default_callable}],

しかし、私は得る

NameError: name 'default_callable' is not defined

そして私はこれを修正する方法の手がかりを持っていません、どんな助けもありがたいです。

4

2 に答える 2

3

南部で使用されるフィールドに呼び出し可能な引数を渡す方法

そのようなフィールド クラスがあり、それを南で動作させたい --- 問題は、callable であり、凍結できない default_callable 引数にあります。

class DependentIntegerField(models.IntegerField):

 def __init__(self, default_callable, *args, **kwargs):
      self.default_callable = default_callable
      super(DependentIntegerField, self).__init__(*args, **kwargs)

この引数を無視する

この引数を完全に残すのはどうですか --- フィールドでオプションにして、この引数をイントラスペクション ルールから削除します (そのため、その存在を無視します) --- 呼び出し可能な引数がフィールドのデータベースの動作を変更しないことを収集します --- そして南が関心を持っているのはそれだけです。この引数で null を許可します (そして、データベース操作を実行するときにフィールドを失敗させます --- モデル インスタンスの保存など --- null を使用しますdefault_callable

サウスはモデルを保存しないため、サウスの実行中は問題ありません --- データベース テーブルを作成するだけで、通常の操作中models.pyは、設定されるファイルからモデル定義が取得されますdefault_callable

呼び出す関数に関する情報を渡す

default_callable一部のモジュールでは、文字列キーでアクセスできる関数の辞書を作成します。

フィールドを次のように変更します。

 class DependentIntegerField(models.IntegerField):

 def __init__(self, default_callable="foo.bar", *args, **kwargs):
      self.default_callable = default_callable #it it string now!
      super(DependentIntegerField, self).__init__(*args, **kwargs)

 @property
 def default_fun(self):
     return registry[self.default_callable]

registry は、すべてのデフォルト関数の辞書です。

于 2012-07-26T08:53:15.200 に答える
1

イントロスペクション ルールは基本的に、どのプロパティがどのようにコンストラクター引数に変換されるかを南に伝えます。たとえば、toからのコンストラクタ引数はForeignKeyプロパティに変換されますfield.rel.toさらに、モデルではなくフィールドのイントロスペクションを定義します

コードでも同じです。フィールド南へのコンストラクター呼び出しを構築するとき、フィールドプロパティdefault_callableが同じ名前のコンストラクター引数に変換されることを知っている必要があります。したがって、イントロスベクション ルールは次のように定義する必要があると思います。

add_introspection_rules([
(
    [DependentIntegerField], # Notice it is for a field not a model 
    [],         # Positional arguments (not used)
    {           # Keyword argument
        "default_callable": ["default_callable", {'default' : <<some defined constant>>}],
    },
),
], ["^shoghlanah\.models\.DependentIntegerField"])

はどうかと言うと:

  NameError: name 'default_callable' is not defined

関数 default_callable が現在のスコープで定義されていなかったと思います。

于 2012-07-25T16:16:21.433 に答える