2010-12-18 28 views
11

का उपयोग करके "पूर्ववत करें" सुविधा को कार्यान्वित करने के लिए कैसे करें मेरे पास एक Django एप्लिकेशन है जहां मैं उपयोगकर्ता को संपर्क डेटा (सदस्यता #, पहला नाम, अंतिम नाम इत्यादि) के साथ एक CSV फ़ाइल आयात करने की अनुमति देता है।पायथन/Django

जब वे फ़ाइल आयात करते हैं, तो एप्लिकेशन मेल खाने वाले रिकॉर्ड के लिए डेटाबेस की जांच करता है और या तो: 1) यदि कोई मिलान मौजूद नहीं है, या 2) नए डेटा के साथ मौजूदा डेटा अपडेट करता है तो एक नया रिकॉर्ड डाला जाता है।

मेरे सवाल यह है: एक पूर्ववत् सुविधा को लागू करने के लिए सबसे अच्छा तरीका क्या है, Django या सीधे अजगर का उपयोग कर, ताकि एक उपयोगकर्ता आयात आपरेशन वापस अपनी मूल स्थिति में पूर्ववत और कई रिकॉर्ड वापस कर सकते हैं? उपयोगकर्ता क्लिक

Table HISTORY 
    unique_id 
    record_affected_id 
    old_value 
    new_value 

फिर अगर "पूर्ववत करें" मैं unique_id कि उनके लेन-देन के साथ जुड़े और हर रिकॉर्ड बनाया है देख सकते हैं:

मेरे प्रारंभिक विचार इस (छद्म कोड) की तरह एक तालिका बनाने के लिए कर रहे हैं पुराने लेन-देन से उस लेनदेन से प्रभावित।

मुझे आश्चर्य है कि ऐसा करने का एक आसान तरीका है कि मुझे याद आ रही है, या अगर किसी के पास ऐसा कुछ अनुभव है।

उत्तर

10

django-reversion पर एक नज़र डालें। यह Django मॉडल के लिए संस्करण नियंत्रण प्रदान करता है। मौजूदा परियोजना में आसानी से जोड़ा जा सकता है।

यह "वर्तमान" सूचक दृष्टिकोण को नियोजित नहीं करता है। इसके बजाए, यह हर बार ऑब्जेक्ट को क्रमबद्ध करता है जब इसे सहेजा जा रहा है और इसे इस ऑब्जेक्ट पर इंगित सामान्य विदेशी कुंजी के साथ अलग Version मॉडल में संग्रहीत करता है। (रिलेशनशिप फ़ील्ड्स को डिफ़ॉल्ट रूप से प्राथमिक कुंजी के रूप में क्रमबद्ध किया जाता है।) इसके अलावा, यह Version एस को Revision एस में लचीला तरीके से समूहित करने की अनुमति देता है।

तो तुम ऐसा ही कुछ कर सकते हैं:

  • उपयोगकर्ता अपलोड करता है सीएसवी, बस हमेशा की तरह परिवर्तनों को सहेजने के लिए, लेकिन समारोह जो करता @revision.create_on_success डेकोरेटर जोड़ने आयात ताकि द्वारा किए गए रिकॉर्ड में कोई भी परिवर्तन समारोह एक संशोधन के तहत संग्रहीत किया जाएगा।
  • जब उपयोगकर्ता "पूर्ववत करें" हिट करता है, तो आप केवल नवीनतम संशोधन को वापस कर देते हैं।

यहाँ यह कैसे किया जा सकता है ::

@revision.create_on_success 
def import_csv(request, csv): 
    # Old versions of all objects save()d here will 
    # belong to single revision. 

def undo_last_csv_import(request): 
    # First, get latest revision saved by this user. 
    # (Assuming you create revisions only when user imports a CSV 
    # and do not version control other data.) 
    revision = Revision.objects.filter(user=request.user)\ 
     .order_by('-date_created')[0] 
    # And revert it, delete=True means we want to delete 
    # any newly added records as well 
    revision.revert(delete=True) 

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

def undo_last_csv_import(request): 
    some_record = Record.objects.by_user(request.user).from_the_last_import()[0] 
    latest_saved_version_of_some_record = Version.objects.get_for_date(
     some_record, 
     datetime.now(), # The latest saved Version at the moment. 
     ) 
    # Revert all versions that belong to the same revision 
    # as the version we got above. 
    latest_saved_version_of_some_record.revision.revert() 

यह एक सुंदर समाधान नहीं है, निश्चित रूप से इस ऐप के साथ बेहतर तरीके से करने के तरीके हैं। मैं बेहतर समझने के लिए कोड को देखने की सलाह देता हूं कि django-reversion कैसे काम करता है-बहुत अच्छी तरह से प्रलेखित, डॉकस्ट्रिंग के बिना कोई फ़ंक्शन नहीं मिला।^_^घ

(प्रलेखन भी अच्छा है, लेकिन पता चला थोड़ा मेरे लिए भ्रामक, यानी वे Version.objects.get_for_date(your_model, date) लिखते हैं, जहां your_model वास्तव में एक मॉडल के उदाहरण है किया जाना है।)

अद्यतन: Django-प्रत्यावर्तन सक्रिय रूप से बनाए रखा जाता है, इसलिए ऊपर दिए गए कोड पर भरोसा न करें, और wiki को बेहतर तरीके से जांचें कि संस्करण & django के व्यवस्थापक के बाहर संशोधन कैसे प्रबंधित करें। उदाहरण के लिए, संशोधन टिप्पणियां पहले ही समर्थित हैं, जो चीजों को थोड़ा सा सरल बना सकती हैं।

3

आपको संस्करण नियंत्रण होना चाहिए, और समस्या यह है कि पाइथन या Django नहीं है, बल्कि यह करने के लिए डेटाबेस को कैसे डिज़ाइन किया जाए। एक आम तरीका है अद्वितीय आईडी के साथ दस्तावेज़ों को स्टोर करना और ट्रैक रखना "चालू" है। पूर्ववत करें केवल "वर्तमान" सूचक को पुराने संशोधन में डालने का मामला है। यह है, जहां तक ​​मैं देख सकता हूं, आप क्या कर रहे हैं।

हालांकि यह करने का यह सामान्य तरीका है, मुझे नहीं पता कि यह सबसे अच्छा है या नहीं। मैंने कभी और कोई रास्ता नहीं देखा है, जिसका अर्थ यह हो सकता है कि यह सबसे अच्छा है, या सबसे अच्छा तरीका अनजान है। :-)

Django में एक सामान्य तरीके से ऐसा करना शायद एक कठिन समस्या है, लेकिन यदि आप अपने Django ऐप को कस्टम तरीके से समर्थन देते हैं तो यह आसान होगा।

फिर आप "भविष्य" संशोधन में चीजों को संपादित करने के तरीके जैसे मज़ा (नहीं) मुद्दों में शामिल हो जाते हैं और फिर सामग्री के एक प्रकार के तरीके में दस्तावेज़ों का एक पूरा सेट प्रकाशित करते हैं। लेकिन उम्मीद है कि आपको इसकी आवश्यकता नहीं है। :-)

1

आपकी इतिहास तालिका ठीक दिखती है, सिवाय इसके कि आपको पूर्ववत करने के लिए new_value फ़ील्ड की आवश्यकता नहीं है। और हां, वह 'कैसे "पूर्ववत" अक्सर कार्यान्वित किया जाता है (दूसरा विकल्प सभी रिकॉर्ड में संस्करण संख्या डालने के लिए लेनार्ट का दृष्टिकोण है)। एक अलग जर्नल टेबल का लाभ यह है कि आपको नियमित प्रश्नों में संस्करण संख्या से निपटने की आवश्यकता नहीं है।