कारण यह है कि विशेष रूप से ModelChoiceField
जब विकल्प पैदा करने एक हिट बनाता है - चाहे क्वेरीसमूह पहले से भर जाने के बाद की परवाह किए बिना - इस लाइन
for obj in self.queryset.all():
django.forms.models.ModelChoiceIterator
में
में निहित है। Django documentation on caching of QuerySets पर प्रकाश डाला के रूप में,
callable attributes cause DB lookups every time.
तो मैं सिर्फ
for obj in self.queryset:
उपयोग करने के लिए भले ही मैं नहीं कर रहा हूँ 100% यह सब प्रभाव के बारे में यकीन है कि पसंद करते हैं (मुझे पता है कि मैं बड़ा नहीं है बाद में क्वेरीसेट के साथ योजनाएं, इसलिए मुझे लगता है कि मैं कॉपी के बिना ठीक हूं .all()
बनाता है)। मैं स्रोत कोड में बदल करने के लिए परीक्षा रहा हूँ, लेकिन जब से मैं अगले पर इसके बारे में भूल जाते हैं करने जा रहा हूँ स्थापित (और यह बुरा शैली के साथ शुरू करने के लिए है) मैं अपने कस्टम ModelChoiceField
लेखन समाप्त हो गया:
class MyModelChoiceIterator(forms.models.ModelChoiceIterator):
"""note that only line with # *** in it is actually changed"""
def __init__(self, field):
forms.models.ModelChoiceIterator.__init__(self, field)
def __iter__(self):
if self.field.empty_label is not None:
yield (u"", self.field.empty_label)
if self.field.cache_choices:
if self.field.choice_cache is None:
self.field.choice_cache = [
self.choice(obj) for obj in self.queryset.all()
]
for choice in self.field.choice_cache:
yield choice
else:
for obj in self.queryset: # ***
yield self.choice(obj)
class MyModelChoiceField(forms.ModelChoiceField):
"""only purpose of this class is to call another ModelChoiceIterator"""
def __init__(*args, **kwargs):
forms.ModelChoiceField.__init__(*args, **kwargs)
def _get_choices(self):
if hasattr(self, '_choices'):
return self._choices
return MyModelChoiceIterator(self)
choices = property(_get_choices, forms.ModelChoiceField._set_choices)
यह डेटाबेस कैशिंग की सामान्य समस्या को हल नहीं करता है, लेकिन चूंकि आप विशेष रूप से ModelChoiceField
के बारे में पूछ रहे हैं और यह वही है जो मुझे पहले कैशिंग के बारे में सोचने लगा, सोचा कि इससे मदद मिल सकती है।
यह एक अच्छा समाधान है और Django 1.8 में पूरी तरह से काम करता है। दो मामूली सुझाव जो कोड को थोड़ा क्लीनर बना सकते हैं: 1) आप दोनों वर्गों से '__init __()' को हटा सकते हैं, क्योंकि वे नो-ऑप्स हैं। 2) Django 1.9 में 'cache_choices' हटा दिया गया है, ताकि आप कोड के उस पूरे टुकड़े को पट्टी कर सकें। – Chad
हाय, मैं इस समय Django का उपयोग नहीं कर रहा हूं इसलिए मेरे पास कोई वर्तमान Django सेट अप नहीं है और इसलिए इसे सत्यापित करने का तरीका है। इसे कोड में बदलने के लिए अनिच्छुक मैं परीक्षण नहीं कर सकता - आपके बारे में कोड के साथ उत्तर कैसे बनाते हैं और मैं आपके उत्तर से लिंक करने के लिए नीचे इस पोस्ट को संपादित करता हूं? – Nicolas78