2010-09-08 22 views
8

में सप्ताह के दिनों के लिए एक बहु-चयन क्षेत्र का प्रतिनिधित्व करना मैं एक Django मॉडल में एक बहु-चयन सप्ताहांत क्षेत्र (सोम, मंगल, बुध ...) का प्रतिनिधित्व करने के लिए एक शानदार तरीका खोज रहा हूं। मैं शुरुआत में बिटवाइथ गणित का उपयोग करके पूर्णांक क्षेत्र जाने का विचार कर रहा था लेकिन मुझे यकीन नहीं है कि यह जाने का तरीका होगा या नहीं।एक Django मॉडल

यह अधिकतर पढ़ा जाने वाला क्षेत्र होगा। मैं चाहता हूं कि क्वेरीसेट विधि Entry.objects.get(weekdays__contains=MONDAY) जैसी कुछ हो, जहां MONDAY स्थिर रहेगा।

शायद कोई बेहतर समाधान के साथ आ सकता है? या शायद किसी ने कुछ ऐसा किया है और कुछ उदाहरण कोड है जो वे योगदान दे सकते हैं?

+0

अधिक जानकारी के बिना (डेटासेट का आकार, ज्यादातर पढ़ना बनाम ज्यादातर लिखना आदि) बिटफील्ड के साथ जाने से भयभीत समयपूर्व अनुकूलन की तरह लगता है। –

+0

मैं प्रश्न के लिए अतिरिक्त जानकारी जोड़ूंगा। धन्यवाद श्री रोवेल। –

+0

क्या आपने 'सप्ताहांत' मॉडल और प्रश्न के मॉडल के बीच कई रिश्तों को जोड़ने पर विचार किया है? मुझे पता है कि यह एक ओवरकिल का थोड़ा सा है क्योंकि उस सप्ताह के दिनों में निश्चित रूप से तय किया गया है, लेकिन यह फ़िल्टरिंग को बहुत सरल बना देगा। –

उत्तर

14

यह एक पुराना सवाल है, लेकिन मैंने सोचा कि मैं दिखाऊंगा कि यह कैसे डैंजो में उचित रूप से किया जा सकता है।

class BitChoices(object): 
    def __init__(self, choices): 
    self._choices = [] 
    self._lookup = {} 
    for index, (key, val) in enumerate(choices): 
     index = 2**index 
     self._choices.append((index, val)) 
     self._lookup[key] = index 

    def __iter__(self): 
    return iter(self._choices) 

    def __len__(self): 
    return len(self._choices) 

    def __getattr__(self, attr): 
    try: 
     return self._lookup[attr] 
    except KeyError: 
     raise AttributeError(attr) 

    def get_selected_keys(self, selection): 
    """ Return a list of keys for the given selection """ 
    return [ k for k,b in self._lookup.iteritems() if b & selection] 

    def get_selected_values(self, selection): 
    """ Return a list of values for the given selection """ 
    return [ v for b,v in self._choices if b & selection] 

एक PositiveIntegerField के साथ अपने मॉडल को परिभाषित करें, और विकल्प आप चाहते हैं:

WEEKDAYS = BitChoices((('mon', 'Monday'), ('tue', 'Tuesday'), ('wed', 'Wednesday'), 
       ('thu', 'Thursday'), ('fri', 'Friday'), ('sat', 'Saturday'), 
       ('sun', 'Sunday') 
      )) 

इसका मतलब है आप की तरह मान का उपयोग कर सकते

यहाँ अपने विकल्पों की तैयारी के लिए एक सहायक वर्ग है यह:

>>> print list(WEEKDAYS) 
[(1, 'Monday'), (2, 'Tuesday'), (4, 'Wednesday'), (8, 'Thursday'), (16, 'Friday'), (32, 'Saturday'), (64, 'Sunday')] 
>>> print WEEKDAYS.fri 
16 
>>> print WEEKDAYS.get_selected_values(52) 
['Wednesday', 'Friday', 'Saturday'] 

अब अपने मॉडल कोके साथ परिभाषित करेंऔर ये विकल्प:

class Entry(models.Model): 
    weekdays = models.PositiveIntegerField(choices=WEEKDAYS) 

और आपके मॉडल किए जाते हैं। प्रश्नों के लिए, निम्नलिखित काम कर देता है:

Entry.objects.extra(where=["weekdays & %s"], params=[WEEKDAYS.fri]) 

वहाँ एक Q() वस्तु उपवर्ग है कि बड़े करीने से प्रश्नों पैकेज बनाने के लिए एक तरीका हो सकता है, इसलिए वे इस तरह दिखेगा: एक पर

Entry.objects.filter(HasBit('weekdays', WEEKDAYS.fri)) 

या भी हैक F() उपवर्ग कुछ इस तरह बनाने के लिए:

Entry.objects.filter(weekdays=HasBit(WEEKDAYS.fri)) 

लेकिन मैं इस समय है कि पता लगाने के लिए समय नहीं है। .where ठीक काम करता है और एक क्वेरीसेट फ़ंक्शन में वर्गीकृत किया जा सकता है।

एक अंतिम विचार यह है कि आप कस्टम मॉडल फ़ील्ड बनाने के लिए प्रकाश डाल सकते हैं जो डेटाबेस में बिट मास्क को किसी सूची में परिवर्तित करता है या पायथन में सेट करता है। उपयोगकर्ता को व्यवस्थापक में अपने मूल्यों का चयन करने के लिए आप SelectMultiple विजेट (या CheckboxSelectMultiple) का उपयोग कर सकते हैं।

+0

यह उत्तर http: // stackoverflow।कॉम/प्रश्न/1 9 645227/डीजेंगो-निर्माण-मल्टीइलेक्ट-चेकबॉक्स-इनपुट ब्रोच जो कि टीएच विजेट – Yablargo

+0

के विषय में हैं, बस फिर से धन्यवाद कहना चाहते हैं, मैं आपकी कक्षा के खिलाफ एक विजेट बनाने के माध्यम से ठोकर खा सकता था, और यह एक चैंप की तरह काम करता है। – Yablargo

+0

@Yablargo और लेखक: बहुत बहुत धन्यवाद! मैं भी आपकी कक्षा के खिलाफ एक विजेट बनाने में सक्षम था, लेकिन मैं रिवर्स फ़ंक्शन ((स्ट्रिंग) मान से (चलो कहता हूं "12") डेटामैटिक {(4, "wednesday"), (8, " thursday ")} प्रारंभिक डेटा दिखाने और संपादित करने के लिए। क्या आप यहां सहायता कर सकते हैं: http://stackoverflow.com/q/25575951/3849359? धन्यवाद एक लाख! – gabn88

संबंधित मुद्दे