具有多个inheritan的Django自定义字段

2024-10-01 17:37:52 发布

您现在位置:Python中文网/ 问答频道 /正文

我有两个自定义Django字段,JSONFieldCompressedField,这两个字段都工作得很好。我也想要一个CompressedJSONField,我很希望我可以这样做:

class CompressedJSONField(JSONField, CompressedField):
    pass

但在进口上我得到:

^{pr2}$

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

编辑:

为了清楚起见,我不认为这与我的代码的细节有关,因为下面的代码也有相同的问题:

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

编辑2:

目前我使用的是python2.6.6和django1.3。下面是我的精简测试示例的完整代码:

customfields.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

models.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时就会出现错误。在


Tags: djangoselffielddbgetreturnvaluemodels
2条回答

在做了一些快速测试后,我发现如果从JSON和compressed字段中删除元类,并将其放入它编译的compressedJSON字段中。如果您需要JSON或压缩字段,那么将它们子类化并jusst添加__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和Commpressed字段,我想这个想法是可行的:

^{pr2}$

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

编辑基本方法破解

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

编辑 在阅读了一些之后,如果您在第一个基中实现了对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    

很难理解你到底是什么时候犯了那个错误。但是看看DJango代码,有simlar实现(多重继承)

参考:类ImageFieldFile(ImageFile,FieldFile)
在django/db/models/fields中

相关问题 更多 >

    热门问题