如何在Django模型中创建简单的自定义字段类型?

2024-04-18 23:13:12 发布

您现在位置:Python中文网/ 问答频道 /正文

我正在尝试在Django中创建一些映射到标准Django类型的类型。custom model field documentation的情况很复杂;我只想用一堆方便的方法存储一个类中的基本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):  ...
     ...

我想让我的模特有这样的东西:

^{pr2}$

我希望答案看起来像是继承了正确的类型,为card添加了一些特殊命名的get/store字段,并重命名init()。有没有人有示例代码或更好的文档?在


Tags: ofdjangoself类型numberfield标准model
3条回答

不要害怕根据自己的需要调整Django中的模型类。他们一点也不神奇。我想这是代码的正确位置:在模型中。在

我会用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或{}。在

to_python方法执行相反的操作,将value转换为Card。与前面一样,您需要处理None作为值的可能性。使用SubfieldBase可以确保每次给字段赋值时都会调用to_python。在

你为什么不能做如下的事情?在

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的自然行为非常吻合。在

相关问题 更多 >