[Django]-How do I create trivial customized field types in Django models?

4👍

I’d do this with a subclass of Django’s 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))

The get_db_prep_value method is responsible for converting value into something suitable for interacting with the database, in this case either an int or None.

The to_python method does the reverse, converting value into a Card. Just like before, you’ll need to handle the possibility of None as a value. Using the SubfieldBase ensures that to_python is called every time a value is assigned to the field.

1👍

Why can’t you do something like the following?

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):...

Certainly, this is quite simple, and fits comfortably with what Django does naturally.

👤S.Lott

0👍

Don’t be afraid to adapt the model classes in Django to your own needs. There’s nothing magical about them. And I guess this is the Right Place for this code: In the model.

👤rebra

Leave a comment