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

如何将可调用参数传递给南方使用的字段

你有这样的字段类,你想让它与南一起工作——问题在于 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 default_callable

在 south run 期间会没问题,因为 south 不保存任何模型 --- 它只是创建数据库表,并且在正常操作期间,模型定义将从models.pydefault_callable设置的文件中获取。

传递有关调用什么函数的信息

在某些模块中,创建default_callable可由字符串键访问的字典 od 函数。

更改您的字段:

 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,构造函数参数 fromForeignKey转换为 property 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 回答