gpt4 book ai didi

python - 具有多重继承的Django自定义字段

转载 作者:太空狗 更新时间:2023-10-30 01:38:50 26 4
gpt4 key购买 nike

我有两个自定义 Django 字段,一个是 JSONField 一个是 CompressedField,两者都运行良好。我还想有一个 CompressedJSONField,我非常希望我能做到这一点:

class CompressedJSONField(JSONField, CompressedField):
pass

但是在导入时我得到:

RuntimeError: maximum recursion depth exceeded while calling a Python object

我可以找到有关在 Django 中使用具有多重继承的模型的信息,但没有关于对字段执行相同操作的信息。这应该是可能的吗?还是我应该在这个阶段放弃?

编辑:

需要说明的是,我认为这与我的代码的细节没有任何关系,因为以下代码有完全相同的问题:

class CustomField(models.TextField, models.CharField):
pass

编辑 2:

我目前使用的是 Python 2.6.6 和 Django 1.3。这是我的精简测试示例的完整代码:

自定义字段.py

from 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

模型.py

from 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

只要添加 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

如果您随后想分别使用 JSON 和压缩字段,我认为这个想法可行:

class JSONFieldSubClass(JSONField):
__metaclass__ = models.SubfieldBase

老实说......我真的不明白这些。

编辑基本方法 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

另一种方法是使类上的 to_python() 具有唯一的名称,并在继承的类中调用它们的 to_python() 方法

或者看看这个 answer

编辑如果您在第一个基础 to_python() 中实现对 super(class, self).method(args) 的调用,那么它会调用第二个基础。如果你一直使用 super 那么你应该没有任何问题。 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

关于python - 具有多重继承的Django自定义字段,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/5524241/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com