2013-03-04 4 views
6

में हर रूप के लिए विदेशी के विकल्पों के लिए पूछताछ से Django को रोकें। मैं अपने Django आवेदन के लिए एक सीएसवी आयात फ़ॉर्म बना रहा हूं और ModelFormSet में वैध उद्देश्यों के लिए आयातित पंक्तियां प्रदर्शित करना चाहता हूं।मॉडलफॉर्मसेट

इसलिए मैंने प्रासंगिक ModelAdmin पर एक दृश्य जोड़ा जो सीएसवी से लाइनें पढ़ता है और ModelFormSet(queryset=an_empty_queryset, initial={data_from_the_csv}) प्रिंट करता है।

समस्या मॉडल ForeignKey क्षेत्रों के माध्यम से और के लिए प्रत्येक क्षेत्र तीन अन्य मॉडलों का संदर्भ देता है प्रत्येक प्रपत्र formset में एक डेटाबेस क्वेरी आदेश ModelChoiceField के विकल्पों को भरने के लिए जारी किया गया है में है।

क्यों Django प्रपत्र कैश नहीं करता है (के रूप में यह कई बार प्रयोग किया जाता है) या वहाँ पहले से ही इस बारे में मैं अभी तक पता नहीं पूरा करने के लिए एक तरीका है?

+1

django1.5 मॉडल स्मृति कैश है। – danihp

+1

आप सही (https://docs.djangoproject.com/en/1.5/releases/1.5/#caching-of-related-model-instances) कर रहे हैं, लेकिन दुर्भाग्य से यह इस समस्या को प्रभावित नहीं करता। – jnns

+0

मैंने इस समस्या को हल करने के लिए थोड़ा हैक बनाया है: http://stackoverflow.com/a/43105646/8450 –

उत्तर

11

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

कैशिंग भी दुष्प्रभाव अनपेक्षित हो सकता था - उदाहरण के लिए, प्रपत्र के __init__ समारोह initial डेटा इसे प्राप्त किया पर निर्भर हो सकता है, कैश की गई form वस्तु गलत बना रही है।

सबसे अच्छा प्रश्नों की संख्या को कम करने के लिए एक बार चुनाव क्वेरीसमूहों निकालते हैं और फिर उनके निर्माता अपने फ़ॉर्म वर्गों के लिए उन्हें पारित करने के लिए किया जाएगा जिस तरह से। यह एक कस्टम ModelForm और एक कस्टम ModelFormSet को परिभाषित करने की आवश्यकता होगी।

आपका प्रपत्र एक निर्माता है कि विकल्प सीधे स्वीकार करता है की आवश्यकता होगी:

from django.forms.models import ModelForm 

class MyForm(ModelForm): 
    def __init__(self, my_field_choices=None, *args, **kwargs): 
     super(MyForm, self).__init__(*args, **kwargs) 
     self.fields['my_field'].choices = my_field_choices 

और अपने formset के रूप में वे का निर्माण कर रहे हैं क्वेरीसमूहों चलाने के लिए और उन्हें रूपों में पारित करने के लिए एक विधि ओवरराइड करने के लिए की आवश्यकता होगी:

from django.forms.models import BaseModelFormSet 

class MyFormSet(BaseModelFormSet): 
    def _construct_forms(self): 
     # instantiate all the forms and put them in self.forms 
     self.forms = [] 

     # Define each of your choices querysets 
     my_field_choices = Model.object.filter(...) 

     #Add your querysets to a dict to pass to the form 
     form_defaults = {'my_field_choices': my_field_choices, } 

     for i in xrange(min(self.total_form_count(), self.absolute_max)): 
      self.forms.append(self._construct_form(i, **form_defaults)) 

(the Django source कि यह कैसे काम करेगा इस पर गौर करने के लिए)

+0

मेरे प्रश्न का उत्तर देने के लिए समय निकालने के लिए धन्यवाद। आपका समाधान वह है जो मुझे दिमाग में था, लेकिन अब मुझे पता है कि यह जाने का रास्ता है! – jnns

+0

मैंने इस समाधान का उपयोग एक ही समस्या के लिए किया था, लेकिन जब मुझे सहेज रहा है तो मुझे "असाइन नहीं किया जा सकता" u'7 '":" Stop.city "एक" शहर "उदाहरण होना चाहिए।" स्टॉप मॉडलफॉर्म (फॉर्मेट बनाने के लिए प्रयुक्त होता है) जिसमें सिटी एफके है। क्या आप इसके चारों ओर पारित कर सकते हैं ?, ऐसा लगता है कि इस तरह आगे जाने के लिए यह बहुत अधिक है। – mariodev

+0

@mariodev, मुझे लगता है कि आपको इस मुद्दे को समझाने/ट्रैक करने में सहायता के लिए कुछ और कोड पोस्ट करने की आवश्यकता हो सकती है। इस न्याय को करने के लिए टिप्पणियों में शायद पर्याप्त जगह नहीं है, इसलिए यह शायद अपने प्रश्न के लिए अधिक उपयुक्त है। –