简体   繁体   中英

Django inheritance from models.CharField with choices gives error

I have two classes which are used in application logic. One is called Direction and the other is called Compass. Direction is a member of Compass. What I am trying to implement is a modelField that wraps the Direction class and that I can use as a member in the Compass model. The DirectionField class inherits from models.CharField and sets choices from the parent class.

I think that this is a nice design because I can use the DirectionField in many other classes and it's easy to maintain. However, I get an error when I save the Compass model in the Admin page in Django. The error is "Value is not a valid choice."

I use Python 2.7 and Django 1.4.

Could someone please review this issue and suggest what the problem is and how I could resolve it.

Here is the source:

class Direction():
    choices = (('N','North'),
               ('S','South'),
               ('E','East'),
               ('W','West'),)

    def __init__(self, value=None):
        self.value = value

class DirectionField(models.CharField):

    def __init__(self, *args, **kwargs):
        super(DirectionField, self).__init__(choices=Direction.choices,
                                             *args, **kwargs)

    __metaclass__ = models.SubfieldBase

    def to_python(self, value):
        if isinstance(value, Direction) or value is None:
            return value
        return Direction(value)

    def get_prep_value(self, value):
        return value.value

class Compass(models.Model):
    name = models.CharField(max_length=20)
    direction = modelFields.DirectionField(max_length=10)
    class Meta:
        db_table = 'campass'
    def __unicode__(self):
        return "%s/%s" % (self.name, self.direction)    

class CompassForm(forms.ModelForm):
    class Meta:
        model = Compass
    def clean(self):
        return self.cleaned_data

Error in the Admin page (or form view) that I get when I save Compass:

Value <src.bo.tgEnum.Direction instance at 0x03E97E18> is not a valid choice.

To pass field validation you need to add this functions to Direction class:

def __eq__(self, value):
    return self.value == value

def __len__(self):
    return len(self.value)

Because it compares value with choices keys and value has Dictionary type, key is string.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM