2016-02-10 9 views
9

Django में मैं ट्रैक करना चाहता हूं कि समूह को उपयोगकर्ता को कैसे सौंपा गया है, अभी हम Django व्यवस्थापक के माध्यम से उपयोगकर्ता को समूह असाइन कर रहे हैं। मैंने User.groups.through तालिका पर m2m_changed सिग्नल का उपयोग करने की कोशिश की लेकिन Django व्यवस्थापक में जब उपयोगकर्ता को असाइन किया गया समूह तो यह पहले उपयोगकर्ता के मौजूदा समूहों को साफ़ करता है और अद्यतन समूहों को जोड़ता है, इसलिए यह "pre_clear" और "post_clear" कार्रवाई के लिए अनावश्यक कॉल बनाता है संकेत इसलिए सिग्नल सभी मामलों में काम नहीं कर रहा है।django व्यवस्थापक में उपयोगकर्ता समूह असाइनमेंट ट्रैक

क्या कोई मुझे Django उपयोगकर्ता सहेजने की विधि को ओवरराइड करने और उस विधि में परिवर्तित समूह को संभालने का तरीका सुझा सकता है? या उपयोगकर्ता समूह असाइनमेंट को ट्रैक करने का कोई अन्य तरीका?

मैं Django 1.6

+0

मुझे लगता है कि आप कुछ कोड दिखा सकते हैं, ताकि अन्य आपको बेहतर समझ सकें और समाधान पोस्ट कर सकें। – pktangyue

उत्तर

5

Django का एक ज्ञात समस्या है कि उपयोग कर रहा हूँ और यह केवल 1.9 में तय किया गया था: https://docs.djangoproject.com/en/1.9/releases/1.9/#related-set-direct-assignment

ओआरएम में संबंधित वस्तुओं का प्रत्यक्ष असाइनमेंट स्पष्ट() को जोड़ने के लिए कॉल() के बाद किया जाता था। इससे असुरक्षित रूप से बड़े डेटा परिवर्तन हुए और एम 2 एम_changed सिग्नल का उपयोग करके व्यक्तिगत कई-से-कई संबंधों में परिवर्तनों को ट्रैक करने के लिए रोक दिया गया।

डायरेक्ट असाइनमेंट अब संबंधित प्रबंधकों पर नई सेट() विधि पर निर्भर करता है जो डिफ़ॉल्ट रूप से केवल मौजूदा संबंधित सेट और जो नया असाइन किया गया है, के बीच परिवर्तन को संसाधित करता है। पिछले व्यवहार को कीवर्ड तर्क स्पष्ट = सही के साथ सेट() पर कॉल द्वारा प्रत्यक्ष असाइनमेंट को प्रतिस्थापित करके पुनर्स्थापित किया जा सकता है।

मॉडलफॉर्म, और इसलिए मॉडलएडमिन, आंतरिक रूप से प्रत्यक्ष पर कई रिश्तों के लिए असाइनमेंट पर भरोसा करते हैं और परिणामस्वरूप अब नए व्यवहार का उपयोग करें।

यदि आप मैन्युअल रूप से user.groups.add(foo) या user.groups.remove(foo) का उपयोग कर रहे थे तो आपके वर्तमान सिग्नल रिसीवर को ठीक काम करना चाहिए। लेकिन django व्यवस्थापक असाइनमेंट का उपयोग करता है, इसलिए यह django-admin से प्रत्येक सहेजने पर स्पष्ट और सेट करता है। Django 1.9 को अपडेट किए बिना इस समस्या को ठीक करने के लिए आपको pre_clear और post_add दोनों को संसाधित करना होगा: स्टोर को pks को प्रीक्लियर में उदाहरण के कुछ "विशेष" विशेषता को साफ़ किया गया है और उसके बाद जो जोड़ा या हटाया गया था उसकी गणना करें।

def pre_clear_handler(sender, *args, **kwargs): 
    # ... 
    instance._cleared_groups_pk_set = set([group.pk for group in instance.groups.all()]) # or `set(instance.groups.all().values_list('pk', flat=True)) 
    tracker = SomeTrackingModel() 
    tracker.removed_group_ids = instance._cleared_groups_pk_set 
    tracker.save() # post_add may not be called if groups are fully cleared 
    instance._changes_tracker_helper = tracker 

def post_add_handler(sender, *args, **kwargs): 
    # ... 
    prev_groups_pk_set = getattr(instance, '_cleared_groups_pk_set', None) 
    if prev_groups_pk_set is not None: 
     not_realy_added_pk_set = kwargs['pk_set'] 
     removed_pks = prev_groups_pk_set - not_realy_added_pk_set 
     realy_added_pks = not_realy_added_pk_set - prev_groups_pk_set 
    else: 
     removed_pks = set() 
     realy_added_pks = kwargs['pk_set'] 
    tracker = getattr(instance, '_changes_tracker_helper', SomeTrackingModel()) 
    tracker.removed_group_ids = removed_pks 
    tracker.added_group_ids = realy_added_pks 
    tracker.save() 
+0

हां अभी मैं इसे उसी तरह से संभालने में काम कर रहा हूं, लेकिन जब सभी समूहों को हटा दिया जाता है तो केवल pre_clear कहा जाता है और post_add कॉल नहीं कर रहा है, तो मैं कैसे पता लगा सकता हूं कि सभी समूहों को इस सिग्नल का उपयोग करके हटा दिया गया है? नोट: किसी कारण से मैं अब 1.9 तक अपग्रेड नहीं कर सकता। – Yogesh

+0

संभावित समाधान pre_clear में परिवर्तनों को सहेजना और उदाहरण में "ऑब्जेक्ट बदलें" ट्रैक करना होगा ('...; tracker.removed_group_ids = instance._cleared_groups_pk_set; tracker.save(); instance.change_tracker = tracker')। और post_add में: एक को सही करने के लिए ट्रैक किए गए परिवर्तनों को वापस या संशोधित करें और फिर से सहेजें ('instance.change_tracker.removed_group_ids = remove_pks; ...; example.change_tracker.save()'। इस तरह post_add के बिना pre_clear को भी ट्रैक किया जाएगा – imposeren

+0

अपडेट किया गया यह दिखाने के लिए कि समूहों को पूरी तरह से साफ़ करने और/या केवल जोड़े जाने पर कैसे संभालना है – imposeren

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