我试图实现一个自定义的Django字段,它会在DB中保留我的模型类之一的名称(例如“Cat”,“Dog”,“Restaurant” “SuperPrivateCommercialDataPiece”等),并在请求时返回类对象:Django的自定义字段在管理员编辑时出现错误
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字段编辑已存在的对象时开始。首先,它用“猫对象”而不是“猫”填充文本字段。第二,当我改回为“猫”,并点击“保存修改”,它提供了一个错误:
TypeError at /admin/myapp/somedatapiece/3/
unbound method prepare_database_save() must be
called with Cat instance as first argument (got
MyGloriousFieldType instance instead)
那么,我究竟做错了什么?