在管理员中编辑时,Django自定义字段会出错

时间:2013-07-19 12:24:06

标签: django django-admin django-custom-field

我正在尝试实现一个自定义Django字段,该字段会在DB中保留我的某个模型类的名称(例如“Cat”,“Dog”,“Restaurant”,“SuperPrivateCommercialDataPiece”等)并返回请求时的类对象:

class Cat(models.Model):
    ...

class SomeDataPiece(models.Model):
    relatedTo = MyGloriousFieldType(null=True)

...

newPiece = SomeDataPiece()
newPiece.relatedTo = Cat
print newPiece.relatedTo # should print <class 'myproj.myapp.models.Cat'>

我真的做到了这一点。我已经分组models.Field,设置了__metaclass__等等:

class MyGloriousFieldType(models.Field):

    description = "No description, just gloriosity."

    __metaclass__ = models.SubfieldBase

    def __init__(self, *args, **kwargs):
        kwargs['max_length'] = 40
        super(BlockTypeField, self).__init__(*args, **kwargs)

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

    def to_python(self, value):
        if not value:
            return None
        elif inspect.isclass(value) and issubclass(value, models.Model):
            return value
        elif hasattr(myproj.myapp.models, value):
            return getattr(myproj.myapp.models, value)
        else:
            raise ValidationError("Invalid model name string")

    def get_db_prep_value(self, value, **kwargs):
        if inspect.isclass(value) and issubclass(value, models.Model):
            return value.__name__
        else:
            # it is actually never raised
            raise ValidationError("Invalid value, Model subclass expected")

    def value_to_string(self, instance):
        value = self._get_val_from_obj(obj)
        return self.get_prep_value(value)

在上面的代码中,它的工作方式与预期一致。我还在管理员中注册了一些包含这些字段的模型,现在我甚至可以创建这样的对象;为MyGloriousFieldType字段创建文本输入。

当我尝试使用MyGloriousFieldType字段编辑已存在的对象时,危机就开始了。首先,它使用“Cat对象”而不仅仅是“Cat”填充文本字段。其次,当我将其更改回“Cat”并单击“保存更改”时,会出现错误:

TypeError at /admin/myapp/somedatapiece/3/
  unbound method prepare_database_save() must be
  called with Cat instance as first argument (got 
  MyGloriousFieldType instance instead)

那么,我做错了什么?

1 个答案:

答案 0 :(得分:0)

好吧,我已经明白了。问题出在Django核心内部。字段只是不能返回包含models.Fieldprepare_database_save属性的Python对象,否则会发生错误。我解决这个问题的方法是在(MyClassObject, )中返回元组MyClassObject而不是to_python()。奇怪,但我能做些什么......也许我会尝试在Django的Github页面上发布一个问题。