私は 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
どうもありがとう!!