nunos
nunos

Reputation: 21409

Very Simple Django Custom Field

I am trying to do a very simple custom field, but can't seem to get it to work.

Currently, I am adding this field to pretty much all models in my application. I would like to have it specified as a custom field to avoid duplicate code.

identifier = models.CharField(
    max_length = 20, 
    unique = True, validators = [validators.validate_slug],
    help_text = "Help text goes here."
)

What I have is this:

class MyIdentifierField(models.CharField):

    description = "random string goes here"

    __metaclass__ = models.SubfieldBase

    def __init__(self, *args, **kwargs):
        kwargs['max_length'] = 20
        kwargs['unique'] = True
        kwargs['validators'] = [validators.validate_slug]
        kwargs['help_text'] = "custom help text goes here"
        super(MyIdentifierField, self).__init__(*args, **kwargs)

    def db_type(self, connection):
        return 'char(25)'

so that I can use it like this:

identifier = MyIdentifierField()

However, when I do python manage.py schemamigration --auto <myapp>, I am getting the following error:

 ! Cannot freeze field 'geral.seccao.identifier'
 ! (this field has class geral.models.MyIdentifierField)

 ! 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

I have gone through the recommended webpage, but still can't seem to find a workaround this. Any help is appreciated. Thanks.

Upvotes: 5

Views: 601

Answers (1)

Brandon Taylor
Brandon Taylor

Reputation: 34593

You need to help South out a bit when describing your field. There are two methods to do this as documented at: http://south.aeracode.org/wiki/MyFieldsDontWork

My preferred method is to add a South field triple on the field class:

def south_field_triple(self):
    try:
        from south.modelsinspector import introspector
        cls_name = '{0}.{1}'.format(
            self.__class__.__module__,
            self.__class__.__name__)
        args, kwargs = introspector(self)
        return cls_name, args, kwargs
    except ImportError:
        pass

Hope that helps you out.

Upvotes: 6

Related Questions