3

標準の Django 型にマップする Django でいくつかの型を作成しようとしています。カスタム モデル フィールドのドキュメントは、複雑なケースに入ります。便利なメソッドがたくさんあるクラスから基本的な Django 型を保存したいだけです。

たとえば、トランプを保管している場合、次のようなものが必要です。

class Card(object):
    """ A playing card.  """
    def as_number(self):
        """ returns a number from 1 (Ace of Clubs) and 52 (King of Spades)."""
        return self.number + self.suit_rank() * 13
    def __unicode(self): ...
    def is_highest(self, other_cards, trump=None):...
    def __init__(self, number, suit):  ...
     ...

モデルに次のようなものを持たせたい:

class my_game(models.Model):
    ante = models.IntegerField()
    bonus_card = Card()   # Really stored as an models.IntegerField()
    ....

答えは、正しいタイプから継承し、カードに特別な名前の get/store フィールドを追加し、名前をinit () に変更するように見えると予想しています。サンプルコードやより良いドキュメントを持っている人はいますか?

4

3 に答える 3

4

Django の PositiveIntegerField のサブクラスでこれを行います。

from django.db import models

class Card(object):
    """The ``Card`` class you described."""
    ...

class CardField(models.PositiveIntegerField):
    __metaclass__ = models.SubfieldBase

    def get_db_prep_value(self, value):
        """Return the ``int`` equivalent of ``value``."""
        if value is None: return None
        try:
            int_value = value.as_number()
        except AttributeError:
            int_value = int(value)
        return int_value

    def to_python(self, value):
        """Return the ``Card`` equivalent of ``value``."""
        if value is None or isinstance(value, Card):
            return value
        return Card(int(value))

このget_db_prep_valueメソッドはvalue、データベースとの対話に適したもの (この場合は または のいずれか) にint変換する役割を果たしますNone

このto_pythonメソッドは逆の処理を行い、 に変換valueCardます。前と同じように、の可能性を値として処理する必要がありNoneます。を使用するSubfieldBaseto_python、値がフィールドに割り当てられるたびに呼び出されます。

于 2008-12-02T20:27:56.563 に答える
1

次のようなことができないのはなぜですか?

class Card(models.Model):
    """ A playing card.  """
    self.suit = models.PositiveIntegerField()
    self.rank = models.PositiveIntegerField( choices=SUIT_CHOICES )
    def as_number(self):
        """ returns a number from 1 (Ace of Clubs) and 52 (King of Spades)."""
        return self.number + self.suit * 13
    def __unicode__(self):
        return ...
    def is_highest(self, other_cards, trump=None):...

確かに、これは非常に単純で、Django が自然に行うこととうまく適合します。

于 2008-12-02T19:55:40.733 に答える
0

Django のモデル クラスを自分のニーズに合わせることを恐れないでください。それらについて魔法は何もありません。そして、これがこのコードの適切な場所だと思います: モデル内。

于 2008-12-02T20:14:58.960 に答える