我对 Python 和 Django 还很陌生,对 Stack Overflow 也很陌生,所以我希望我不会在这里违反任何规则,并且我尊重问题的格式。
我在尝试使用 Django(Python 3.3.0,Django 1.5a1)实现自定义模型字段时遇到问题,但我没有找到任何类似的主题,我实际上非常坚持这个......
所以有一个玩家,他有一手(牌)。Hand 继承自 CardContainer,它基本上是一个带有一些(隐藏在这里)辅助函数的卡片列表。下面是对应的代码:
from django.db import models
class Card:
def __init__(self, id):
self.id = id
class CardContainer:
def __init__(self, cards=None):
if cards is None:
cards = []
self.cards = cards
class Hand(CardContainer):
def __init__(self, cards=None):
super(Hand, self).__init__(cards)
class CardContainerField(models.CommaSeparatedIntegerField):
__metaclass__ = models.SubfieldBase
def __init__(self, cls, *args, **kwargs):
if not issubclass(cls, CardContainer):
raise TypeError('{} is not a subclass of CardContainer'.format(cls))
self.cls = cls
kwargs['max_length'] = 10
super(CardContainerField, self).__init__(*args, **kwargs)
def to_python(self, value):
if not value:
return self.cls()
if isinstance(value, self.cls):
return value
if isinstance(value, list):
return self.cls([i if isinstance(i, Card) else Card(i) for i in value])
# String: '1,2,3,...'
return self.cls([Card(int(i)) for i in value.split(',')])
def get_prep_value(self, value):
if value is None:
return ''
return ','.join([str(card.id) for card in value.cards])
class Player(models.Model):
hand = CardContainerField(Hand)
但是当我得到一个玩家时,可以这样说:Player.objects.get(id=3).hand
,而不是得到一个Hand
实例(甚至根本不是一个CardContainer
实例!),我只是得到一个逗号分隔的整数字符串,如“1,2,3”,它在数据库中很好(这是我想在数据库中看到的格式)......
在我看来, to_python 没有被调用,所以返回的数据是原始值,因此是字符串。当我搜索这类问题时,人们错过了__metaclass__ = models.SubfieldBase
......我希望我也能错过,但是,嘿,这太简单了!我错过了一些微不足道的事情,还是我错了整件事?:D
非常感谢!!