我對Python和Django相當陌生,在堆棧溢出方面全新,所以我希望我不會在這裏違反任何規則,並且我尊重問題格式。Django自定義模型字段:to_python()沒有調用
我面臨一個問題,試圖用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)
但是,當我得到的球員,可以說,是這樣的:(!甚至CardContainer
實例的話)Player.objects.get(id=3).hand
,而不是讓一個Hand
情況下,我剛開一個逗號分隔的整數字符串,如「1,2,3」,這在數據庫中是正確的(這是我希望在數據庫中看到的格式)...
在我看來,to_python沒有被調用,所以返回的數據是原始值,因此是字符串。當我搜索這種類型的問題時,人們錯過了__metaclass__ = models.SubfieldBase
...我希望我也可以錯過,但是,嘿,這太簡單了! 我錯過了一些微不足道的事情,還是我錯了整件事情? :D
非常感謝!
哇,謝謝,我完全不知道!我認爲它產生的無聲結果非常惱人,我已經爲文檔提交了一個[ticket](https://code.djangoproject.com/ticket/19539)(因爲Django支持Python 3,我認爲文檔應該提到那)。 – astorije