I'm trying to make some types in Django that map to standard Django types. The custom model field documentation goes into complicated cases; I just want to store a basic Django type from a class with a bunch of handy methods.
For example, if I were storing playing cards, I want something like:
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): ...
...
I want my models to have something like:
class my_game(models.Model):
ante = models.IntegerField()
bonus_card = Card() # Really stored as an models.IntegerField()
....
I'm expecting the answer will look like inheriting from the correct type, adding some specially named get/store fields for card, and renaming init(). Does anyone have sample code or better documentation?
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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With