gpt4 book ai didi

python - to_python() 永远不会被调用(即使在 __metaclass__ = models.SubfieldBase 的情况下)

转载 作者:太空宇宙 更新时间:2023-11-03 19:32:03 27 4
gpt4 key购买 nike

前段时间,作为学习Python+Django过程的一部分,我决定为BIT列类型编写一个自定义的MySQL特定的模型字段。不幸的是,我遇到了一个问题。

项目:包含一个“主”应用

“主”应用程序:包含由“python manage.py startapp”创建的所有标准文件,以及 extfields.py

extfields.py内容如下:

from django.db import models
import re
import bitstring

class BitField(models.Field):
description = 'A class representing a field of type "BIT" (MySQL-specific)'
__metaclass__ = models.SubfieldBase

def __init__(self, *args, **kwargs):
bf_size = int(kwargs.pop('bitfield_size', 0))

assert bf_size > 0, '%ss must have a positive bitfield_size' % self.__class__.__name__
self._bf_size = bf_size

super(BitField, self).__init__(*args, **kwargs)


def db_type(self):
return 'BIT(%d)' % self._bf_size


def to_python(self, value):
print('to_python starts')

if isinstance(value, bitstring.BitArray):
return value

value = str(value)

regex = re.compile('^[01]{%d}$' % self._bf_size)

assert regex.search(value) == True, 'The value must be a bit string.'

print('to_python ends')

return bitstring.BitArray(bin=value)


def get_db_prep_value(self, value):
return value.bin

models.py 的内容:

from django.db import models
import extfields

class MessageManager(models.Manager):
"""
This manager is solely for the Message model. We need to alter the default
QuerySet so that we'll get the correct values for the attributes bit field
"""
def get_query_set(self):
return super(MessageManager, self).get_query_set().defer(
'attributes'
).extra(
select={'attributes': 'BIN(attributes)'}
)


class Message(models.Model):
attributes = extfields.BitField(bitfield_size=15)

objects = MessageManager()

当我使用 python shell(通过 python manage.py shell)时,我得到以下信息:

>>> from main import models
>>> m = models.Message.objects.get(pk=1)
>>> m
<Message_Deferred_attributes: Message_Deferred_attributes object>
>>> m.attributes
u'1110001110'
>>> type(m.attributes)
<type 'unicode'>
>>> m.attributes = '1312312'
>>> m.attributes
'1312312'

如您所见,m.attributes 是一个纯字符串,而不是 bitstring.BitArray 实例。

有人可以告诉我哪里出错了吗?

我在 Ubuntu 10.04 上使用 Python 2.6.5。我导入的位串模块是这个:http://code.google.com/p/python-bitstring/ 。 Python-django包版本为1.1.1-2ubuntu1.3。

编辑(回应 emulbreh 的评论):

现在我的 to_python() 定义如下所示:

def to_python(self, value):
print 'to_python'

if isinstance(value, bitstring.BitArray):
return value

print type(value)
value = str(value)
print'\n'
print value
print '\n'
print type(value)

regex = re.compile('^[01]{%d}$' % self._bf_size)

assert regex.search(value) == True, 'The value must be a bit string.'
value = bitstring.BitArray(bin=value)
print '\n'
print type(value)
print 'End of to_python'

return value

控制台输出为:

此后,将引发断言错误。

最佳答案

您无需在 QuerySet 中执行任何特殊操作即可支持自定义字段。您当前 defer() 您的字段,然后添加一个恰好与您的字段同名的原始 extra(select=) 属性。如果您只是删除自定义管理器(或 .defer().extra() 调用),您应该没问题。

关于python - to_python() 永远不会被调用(即使在 __metaclass__ = models.SubfieldBase 的情况下),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/5318837/

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