__init__() takes at least 2 arguments (1 given) When Migrating using South with Custom Fields
Question: **i am new to south and i followed their documentation and after initializing
south migrations, after running**

    
    
    manage.py migrate appname
    

**for the following custom models Models i added introspection rules as
follows**

Models:

    
    
    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)
    

Introspection Rules :

    
    
    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

    
    
    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)
    

i am little sure it's from the field `DependentIntegerField` but i don't know
which `__init__` is it trying to call and i tried

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

but i get

    
    
    NameError: name 'default_callable' is not defined
    

and i have no clues how to fix this, any help is appreciated.


Answer: # How to pass callable argument to field used in south

You have such field class and you want to make it work with south --- problem
is with default_callable argument that is a callable and cannot be frozen.

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

## Ignore this argument

What about leaving this argument altogether --- make it optional on the field
and remove this argument from intrspection rules (so south with ignore it's
existence) --- I gather that callable argument won't change database behaviour
of field --- and that is the only thing south is concerned with. Either allow
nulls in this argument (and make the field fail when performing database
operations --- like saving model instance --- with null `default_callable`.

It will be OK during south run because south doesn't save any models --- it
just creates database tables, and during normal operations model definitions
will be taken from `models.py` file that will have `default_callable` set.

# Pass information about what function to call

In some module create a dictionary od `default_callable` functions that are
accessible by string keys.

Change your field so:

    
    
     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]
    

Where registry is this dictionary of all default functions.

