2013-07-19 46 views
0

我试图实现一个自定义的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) 

那么,我究竟做错了什么?

回答

0

嗯,我已经想通了。问题出在Django的核心。 Fields不能返回包含prepare_database_save之类的一些models.Field属性的Python对象,否则会发生错误。我的黑客解决这个问题是返回元组(MyClassObject,)而不是MyClassObjectto_python()。奇怪的,但我能做什么...也许我会尝试在Django的Github页面上发布一个问题。

相关问题