2012-05-03 15 views
5

करने के लिए किया परिवर्तनों के बाद Django क्वेरी का मूल्यांकन मैं एक दृश्यपुन डेटाबेस

contributions = user_profile.contributions_chosen.all()\ 
    .filter(payed=False).filter(belongs_to=concert)\ 
    .filter(contribution_def__left__gt=0)\ 
    .filter(contribution_def__type_of='ticket') 

मैं अपने टेम्प्लेट में उसका उपयोग वह

context['contributions'] = contributions 

और बाद में उस दृश्य पर मैं परिवर्तन करने पर इस लंबी क्वेरीसमूह बयान मिल गया (तालिका को जोड़ें या हटाएं) तालिका योगदान_चोज़ेन में और यदि मैं अपना संदर्भ ['योगदान'] अपडेट करना चाहता हूं तो मुझे उसी लेंस क्वेरी के साथ डेटाबेस की आवश्यकता होती है।

contributions = user_profile.contributions_chosen.all()\ 
.filter(payed=False).filter(belongs_to=concert)\ 
.filter(contribution_def__left__gt=0)\ 
.filter(contribution_def__type_of='ticket') 

और फिर फिर से अपने संदर्भ अद्यतन

context['contributions'] = contributions 

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

अद्यतन: यह मैं दो संदर्भ के बीच क्या करना [ 'योगदान'] = योगदान

मैं contributions_chosen (यह एक M2M संबंध है) के लिए एक नया योगदान वस्तु जोड़ने के लिए, है

contribution = Contribution.objects.create(kwarg=something,kwarg2=somethingelse) 
user_profile.contributions_chosen.add(contribution) 
contribution.save() 
user_profile.save() 

और कुछ मामलों में मैं एक योगदान वस्तु योगदान = user_profile.contributions_chosen.get (आईडी = 1) user_profile.contributions_chosen.get (आईडी = request.POST [ 'चोर contribution.delete हटाना()

जैसा कि आप देख सकते हैं कि मैं तालिका योगदान_चॉइस संशोधित कर रहा हूं इसलिए मुझे क्वेरी को फिर से जारी करना होगा और संदर्भ को अपडेट करना होगा। मैं क्या गलत कर रहा हूँ?

अद्यतन मूल्यांकन के बारे में अपनी टिप्पणी देखने के बाद, मैं मैं क्वेरीसमूह eval मैं [ 'योगदान'] संदर्भ के बीच लेन (योगदान) करते हैं और है कि समस्या लगती करना एहसास। मैं इसे डेटाबेस संचालन के बाद बस ले जाऊंगा और यह है, धन्यवाद लड़का।

+0

लगता है आप, मूल्यांकन नहीं किया क्वेरीसमूह 'contributions' इस प्रकार यह अद्यतन करने यह अभी भी डीबी से नहीं प्राप्त किए गए डेटा है क्योंकि बारे में चिंता करने की कोई जरूरत नहीं है कर सकते थे। 'QuerySet' आलसी मूल्यांकन है इस प्रकार इसका मूल्यांकन होने तक डीबी पंक्तियों से संबंधित कुछ भी नहीं है। – okm

उत्तर

2

मुझे नहीं पता कि आप क्वेरी का फिर से मूल्यांकन करने से कैसे बच सकते हैं, लेकिन आपके कोड में कुछ बार-बार कथन सहेजने का एक तरीका उन सभी फ़िल्टरों के साथ एक नियम बनाना होगा और filter तर्कों को एक निर्देश के रूप में निर्दिष्ट करना होगा:

query_args = dict(
    payed=False, 
    belongs_to=concert, 
    contribution_def__left__gt=0, 
    contribution_def__type_of='ticket', 
) 

और फिर

contributions = user_profile.contributions_chosen.filter(**query_args) 

यह सिर्फ कुछ दोहराया कोड निकालता है, लेकिन बार-बार क्वेरी का समाधान नहीं करता। आप आर्ग को बदलने की जरूरत है, तो सिर्फ एक सामान्य अजगर dict के रूप में query_args संभाल, यह सब :)

+1

कोड में वह प्रदान करता है कि वह वैसे भी क्वेरी का मूल्यांकन नहीं कर रहा है। क्वेरी का मूल्यांकन तब किया जाता है जब वह टेम्पलेट में इसे फिर से चलाता है या जब वह अन्य सामान करता है जो क्वेरी मूल्यांकन को ट्रिगर करता है, जैसा कि https://docs.djangoproject.com/en/dev/ref/models/querysets/#when-querysets पर प्रलेखित किया गया है -अनु मूल्यांकन –

3

अद्यतन लगता है आप क्वेरीसमूह contributions मूल्यांकन नहीं किया के बाद से एक है, इस प्रकार वहाँ के बारे में चिंता करने की कोई जरूरत नहीं है इसे अपडेट कर रहा है क्योंकि यह अभी भी डीबी से डेटा नहीं लाया है।

क्या आप दो context['contributions'] = contributions लाइनों के बीच कोड पोस्ट कर सकते हैं? आम तौर पर आप क्वेरीसेट contributions का मूल्यांकन करने से पहले (उदाहरण के लिए इसे फिर से भरकर या __len__() पर कॉल करके), इसमें डीबी से कुछ भी नहीं है, इसलिए आपको अपडेट करने की आवश्यकता नहीं है।

एक क्वेरीसमूह फिर से मूल्यांकन के लिए, आपको

# make a clone 
contribution._clone() 
# or any op that makes clone, for example 
contribution.filter() 

# or clear its cache 
contribution._result_cache = None 

# you could even directly add new item to contribution._result_cache, 
# but its could cause unexpected behavior w/o carefulness 
+1

इसके अलावा 'योगदान.all()' –

+0

दस्तावेज़ विशेष रूप से [सभी() '] का उपयोग करने का सुझाव देते हैं (https://docs.djangoproject.com/en/1.11/ref/models/querysets/#all) इस उद्देश्य के लिए। –

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