Search code examples
pythondjangodjango-south

South ValueError: Cannot successfully create field for model: 'module' object has no attribute <CustomClassAttributeHere>


I have a model (/core/models/milestone.py) that uses a custom class as an attribute:

from core.models.IntegerRangeField import IntegerRangeField

    class milestone(models.Model):
        name = models.CharField(max_length=128, null=False, blank=False)
        completion = IntegerRangeField(min_value=0,max_value=100, null=False, default=0, blank=True)
        due_date = models.DateField(null=False, blank=False)
        phase = models.ForeignKey('project_phase',null=False, blank=False)
        last_updated_date = models.DateTimeField(null=False, blank=True, default=datetime.now())

        def __unicode__(self):
            return self.name

(there's actually more code - full copy here)

The custom class it uses is this:

from django.db import models

class IntegerRangeField(models.IntegerField):
    def __init__(self, verbose_name=None, name=None, min_value=None, max_value=None, **kwargs):
        self.min_value, self.max_value = min_value, max_value
        models.IntegerField.__init__(self, verbose_name, name, **kwargs)
    def formfield(self, **kwargs):
        defaults = {'min_value': self.min_value, 'max_value':self.max_value}
        defaults.update(kwargs)
        return super(IntegerRangeField, self).formfield(**defaults)

    class Meta:
        app_label = 'core'

from south.modelsinspector import add_introspection_rules
add_introspection_rules([], ["^core\.models\.IntegerRangeField\.IntegerRangeField"])

With this layout, I am able to run django console, import milestone and play with it.

However, when I run manage.py schemamigration core --auto I get the following error:

ValueError: Cannot successfully create field 'completion' for model 'milestone': 'module' object has no attribute 'IntegerRangeField'.

and nothing gets updated.

I have a feeling it has something to do with cross-importing django.db.models and all but can't figure how to fix this.


Solution

  • So, here is what I've figured:

    the code is fine and the issue is caused by a bit of refactoring I did (the custom field class was originally sitting inside tools module and I wanted it to sit within all the other models and stuff).

    Migrations file had this string:

    ('completion', self.gf('core.tools.IntegerRangeField')(default=0, blank=True)),
    

    and I think this has messed up South in some sort of way to keep looking for core.tools.IntegerRangeField whilst it wasn't there any more.

    I put IntegerRangeField back inside tools.py and it all worked out. Weird.