2012-12-29 12 views
8

नहीं कहा जाता है, मैं पाइथन और डीजेगो के लिए काफी नया हूं, और स्टैक ओवरफ़्लो पर बिल्कुल नया हूं, इसलिए मुझे उम्मीद है कि मैं यहां कोई नियम नहीं तोड़ूंगा और मैं प्रश्न प्रारूप का सम्मान करता हूं।Django कस्टम मॉडल फ़ील्ड: to_python() को

मुझे Django (पायथन 3.3.0, Django 1.5a1) के साथ एक कस्टम मॉडल फ़ील्ड को लागू करने की कोशिश करने में समस्या का सामना करना पड़ रहा है, और मुझे कोई भी समान विषय नहीं मिला, मैं वास्तव में इस पर काफी अटक गया हूं ...

तो एक खिलाड़ी है, उसके पास हाथ (कार्ड) है। हाथ कार्डकॉन्टेनर से विरासत में मिलता है, जो मूल रूप से कुछ (यहां छुपा) सहायक कार्यों के साथ कार्ड की एक सूची है। यहाँ इसी कोड है:

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) 

लेकिन जब मैं एक खिलाड़ी मिल, मान लीजिए कि, इस तरह: (! बिल्कुल या यहां तक ​​कि एक CardContainer उदाहरण) Player.objects.get(id=3).hand, बजाय एक Hand उदाहरण होने का, मैं सिर्फ हो रही है "1,2,3" जैसे पूर्णांक की अल्पविराम से अलग स्ट्रिंग, जो डेटाबेस में ठीक है (यह वह प्रारूप है जिसे मैं डेटाबेस में देखना चाहता हूं) ...

ऐसा लगता है कि to_python कॉल नहीं किया जाता है, इसलिए लौटाया गया डेटा कच्चा मूल्य है, इसलिए स्ट्रिंग। जब मैंने इस तरह की समस्याओं की खोज की, तो लोगों ने __metaclass__ = models.SubfieldBase को याद किया ... मुझे उम्मीद थी कि मैं भी इसे याद कर सकता था, लेकिन, हे, यह बहुत आसान होगा! क्या मुझे कुछ मामूली याद आती है, या क्या मैं पूरी चीज के लिए गलत हूं? : डी

बहुत बहुत धन्यवाद !!

उत्तर

10

पायथन 3 में मॉड्यूल-ग्लोबल __metaclass__ चर अब समर्थित नहीं है। आप का उपयोग करना चाहिए:

class CardContainerField(models.CommaSeparatedIntegerField, metaclass=models.SubfieldBase): 
    ... 
+0

वाह, धन्यवाद, मैं पूरी तरह से है कि पता नहीं था !! मुझे लगता है कि यह चुपचाप परिणाम बनाता है जो काफी परेशान है, और मैंने दस्तावेज के लिए [टिकट] (https://code.djangoproject.com/ticket/19539) सबमिट किया है (जैसे Django Python 3 का समर्थन करता है, मुझे लगता है कि दस्तावेज़ का उल्लेख करना चाहिए उस)। – astorije

0

Django 1.10 के लिए और नवीनतम

class CardContainerField(models.CommaSeparatedIntegerField): 
    def from_db_value(self,value, expression, connection, context): 
     ....... 
संबंधित मुद्दे