2011-02-23 21 views
5

मैं लगातार Django में निम्नलिखित पैटर्न कर रहा हूँ:स्वचालित रूप से एक Django मॉडल में विकल्पों में से प्रत्येक के लिए स्थिरांक जोड़ने

class MyModel(models.Model): 

    FOO = 1 
    BAR = 2 
    GOO = 3 

    BLAH_TYPES = (
     (FOO, 'Foodally boogaly'), 
     (BAR, 'Bar bar bar bar'), 
     (GOO, 'Goo goo gaa gaa'), 
    ) 

    TYPE_FOR_ID = dict(BLAH_TYPES) 

    ID_FOR_TYPE = dict(zip(TYPE_FOR_ID.values(), TYPE_FOR_ID.keys())) 

    blah = models.IntegerField(choices=BLAH_TYPES) 

वहाँ एक अच्छा पैटर्न है कि अन्य लोगों को है कि एक ही प्रभाव को प्राप्त होता है का पालन है (यानी मैं इतने सारे कोड के बिना नाम और शब्दकोश के साथ स्थिरांक तक पहुंच है जो दोनों तरीकों से जाते हैं?

उत्तर

5

कार्ल मेयर की django-model-utils पुस्तकालय के लिए एक उत्कृष्ट समाधान है - विकल्प वर्ग, जो आपको मानव-पठनीय विशेषताओं के माध्यम से विकल्पों के साथ विकल्पों की एक सूची घोषित करने की अनुमति देता है।

0

यह आपके स्थिरांक प्रारंभ करने में सबसे कॉम्पैक्ट तरीके के बारे में है:

# foobar choices constants 
FOO, BAR, BAZ = range(3) 

# bebop choices constants (if you prefer this to readability) 
(BUU, 
BAA, 
DII, 
DUU) = range(4) 

# then, in a galaxy far away, much to your expectations: 
>> FOO 
0 
>> DII 
2 

किसी भी मामले में, मैं आमतौर पर एक const.py कोड़ा और वहाँ (सिर्फ एक है कि 98 लाइनें लंबी है पर देख रहे हैं) सब पागलपन रखने , लेकिन निश्चित रूप से उन्हें मॉडल वर्ग से बाहर ले जाएं और उन्हें समय और स्मृति को बचाने के लिए मॉड्यूल डेटा का हिस्सा बनाएं, जब तक कि आप कुछ गतिशील नहीं करते।

अन्यथा, आप इसे जितना संभव हो उतना अच्छा कर सकते हैं। मैं भी BLAH_TYPES करता हूं, जो डीजेंगो विकल्प संरचना के अनुरूप है, प्रत्येक डेवलपर पढ़ने के आदी है। यह भाग लेने के लिए आप किसी भी शॉर्टकट से बच नहीं सकते हैं और नहीं कर सकते हैं। और, अगर मुझे उन परिवर्तनों की आवश्यकता है, जैसे ID_FOR_TYPE, तो मैं उन्हें विकल्पों के ठीक नीचे परिभाषित करता हूं। पठनीय, साफ और कॉम्पैक्ट।

0

मैं एक ही खुजली था, और है कि मैं क्या लिखा है:

from django.db import models 
from django.db.models.base import ModelBase 
import re 

class ModelBaseWithChoices(ModelBase): 
    def __new__(cls, name, bases, attrs): 
     def format_label(label): 
      return re.sub('[^A-Z]+', '_', label.upper()).strip('_') 

     def get_choices(attrs): 
      for attr, value in attrs.items(): 
       if attr.endswith('_CHOICES') and isinstance(value, tuple): 
        base = '_'.join(attr.split('_')[:-1]) 
        for val, label in value: 
         yield '_'.join((base, format_label(label))), val 

     attrs.update(list(get_choices(attrs))) 
     return super(ModelBaseWithChoices, cls).__new__(cls, name, bases, attrs) 

class ModelWithChoices(models.Model): 
    __metaclass__ = ModelBaseWithChoices 

    class Meta: 
     abstract = True 

वहाँ से, आप MyModel के रूप में फिर से लिखने कर सकते हैं:

class MyModel(ModelWithChoices): 
    BLAH_CHOICES = ((1, 'Foodally boogaly'), 
        (2, 'Bar bar bar bar'), 
        (3, 'Goo goo gaa gaa')) 

    blah = models.IntegerField(choices = BLAH_CHOICES) 

और स्वचालित रूप से आप के लिए बनाए गए सभी स्थिरांक है आदर्श। Django खोल से:

>>> MyModel.BLAH_FOODALLY_BOOGALY 
1 
>>> MyModel.BLAH_GOO_GOO_GAA_GAA 
3 
संबंधित मुद्दे