sim*_*mon 5 python django multiple-inheritance custom-fields
我有两个自定义Django字段,a JSONField和a CompressedField,两者都运行良好.我想也有CompressedJSONField,我希望我能做到这一点:
class CompressedJSONField(JSONField, CompressedField):
pass
Run Code Online (Sandbox Code Playgroud)
但在导入时,我得到:
RuntimeError: maximum recursion depth exceeded while calling a Python object
Run Code Online (Sandbox Code Playgroud)
我可以在Django中找到有关使用具有多重继承的模型的信息,但没有关于对字段执行相同操作的信息.这有可能吗?或者我应该在这个阶段放弃?
编辑:
为了清楚起见,我不认为这与我的代码的细节有任何关系,因为下面的代码有完全相同的问题:
class CustomField(models.TextField, models.CharField):
pass
Run Code Online (Sandbox Code Playgroud)
编辑2:
我目前正在使用Python 2.6.6和Django 1.3.这是我的剥离右下测试示例的完整代码:
customfields.pyfrom django.db import models
class CompressedField(models.TextField):
""" Standard TextField with automatic compression/decompression. """
__metaclass__ = models.SubfieldBase
description = 'Field which compresses stored data.'
def to_python(self, value):
return value
def get_db_prep_value(self, value, **kwargs):
return super(CompressedField, self)\
.get_db_prep_value(value, prepared=True)
class JSONField(models.TextField):
""" JSONField with automatic serialization/deserialization. """
__metaclass__ = models.SubfieldBase
description = 'Field which stores a JSON object'
def to_python(self, value):
return value
def get_db_prep_save(self, value, **kwargs):
return super(JSONField, self).get_db_prep_save(value, **kwargs)
class CompressedJSONField(JSONField, CompressedField):
pass
Run Code Online (Sandbox Code Playgroud)
models.pyfrom django.db import models
from customfields import CompressedField, JSONField, CompressedJSONField
class TestModel(models.Model):
name = models.CharField(max_length=150)
compressed_field = CompressedField()
json_field = JSONField()
compressed_json_field = CompressedJSONField()
def __unicode__(self):
return self.name
Run Code Online (Sandbox Code Playgroud)
一旦我添加该compressed_json_field = CompressedJSONField()行,我在初始化Django时会遇到错误.
经过一些快速测试后,我发现如果您从 JSON 和压缩字段中删除元类并将其放入它编译的压缩JSON 字段中。如果您随后需要 JSON 或压缩字段,则将它们子类化并只需添加__metaclass__ = models.SubfieldBase
我必须承认我没有对此进行任何繁重的测试:
from django.db import models
class CompressedField(models.TextField):
""" Standard TextField with automatic compression/decompression. """
description = 'Field which compresses stored data.'
def to_python(self, value):
return value
def get_db_prep_value(self, value, **kwargs):
return super(CompressedField, self).get_db_prep_value(value, prepared=True)
class JSONField(models.TextField):
""" JSONField with automatic serialization/deserialization. """
description = 'Field which stores a JSON object'
def to_python(self, value):
return value
def get_db_prep_save(self, value, **kwargs):
return super(JSONField, self).get_db_prep_save(value, **kwargs)
class CompressedJSONField(JSONField, CompressedField):
__metaclass__ = models.SubfieldBase
class TestModel(models.Model):
name = models.CharField(max_length=150)
#compressed_field = CompressedField()
#json_field = JSONField()
compressed_json_field = CompressedJSONField()
def __unicode__(self):
return self.name
Run Code Online (Sandbox Code Playgroud)
如果您想分别使用 JSON 和 Compressed 字段,我认为这个想法可行:
class JSONFieldSubClass(JSONField):
__metaclass__ = models.SubfieldBase
Run Code Online (Sandbox Code Playgroud)
老实说......我真的不明白这些。
编辑基本方法 hack
class CompressedJSONField(JSONField, CompressedField):
__metaclass__ = models.SubfieldBase
def to_python(self, value):
value = JSONField.to_python(self, value)
value = CompressedField.to_python(self, value)
return value
Run Code Online (Sandbox Code Playgroud)
另一种方法是使类上的 to_python() 具有唯一的名称,并在继承的类中调用它们 to_python() 方法
或者也许看看这个答案
阅读一些内容后进行编辑,
如果您在第一个基数中实现对 to_python() 的调用super(class, self).method(args),那么它将调用第二个基数。如果你坚持使用超级一致,那么你应该不会有任何问题。http://docs.python.org/library/functions.html#super值得一看,http://www.artima.com/weblogs/viewpost.jsp?thread =237121
class base1(object):
def name(self, value):
print "base1", value
super(base1, self).name(value)
def to_python(self, value):
value = value + " base 1 "
if(hasattr(super(base1, self), "to_python")):
value = super(base1, self).to_python(value)
return value
class base2(object):
def name(self, value):
print "base2", value
def to_python(self, value):
value = value + " base 2 "
if(hasattr(super(base2, self), "to_python")):
value = super(base2, self).to_python(value)
return value
class superClass(base1, base2):
def name(self, value):
super(superClass, self).name(value)
print "super Class", value
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
1315 次 |
| 最近记录: |