Jestem nowicjuszem w Pythonie i Django i całkowicie nowym w Stack Overflow, więc mam nadzieję, że nie złamam tutaj żadnych zasad i szanuję format pytań.Niestandardowe pola modelu Django: to_python() nie nazywane
Mam do czynienia z problemem próbującym zaimplementować niestandardowe pole modelu za pomocą Django (Python 3.3.0, Django 1.5a1), a nie znalazłem żadnych podobnych tematów, właściwie utknąłem na tym ...
Więc jest gracz, ma rękę (karty). Hand dziedziczy po CardContainer, czyli w zasadzie listę kart z niektórymi (ukrytymi tutaj) funkcjami pomocniczymi. Oto odpowiedni kod:
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)
Ale kiedy się odtwarzacz, powiedzmy, na przykład: (! A nawet wystąpienie CardContainer
w ogóle) Player.objects.get(id=3).hand
, zamiast się Hand
instancji, jestem po prostu coraz oddzielony przecinkami ciąg liczb całkowitych, takich jak "1,2,3", co jest w porządku w bazie danych (jest to format, który chciałbym zobaczyć w bazie danych) ...
Wydaje mi się, że to_python nie jest wywoływana, więc zwrócone dane są wartością nieprzetworzoną, stąd ciąg znaków. Kiedy szukałem tego typu problemów, ludzie spóźnili się na __metaclass__ = models.SubfieldBase
... Miałem nadzieję, że też mogłem to przegapić, ale, hej, byłoby to zbyt proste! Czy tęskniłem za czymś trywialnym, czy też nie mam racji? : D
Wielkie dzięki!
Wow, dzięki, ja zupełnie nie wiedziałem, że !! Myślę, że cichy wynik, jaki tworzy, jest dość denerwujący i przesłałem [ticket] (https://code.djangoproject.com/ticket/19539) do dokumentacji (ponieważ Django obsługuje Python 3, myślę, że dokument powinien wspomnieć że). – astorije