2009-02-20 17 views
19

मैं इस तरह एक Django my_forms.py है:लेज़ी विकल्पों

class CarSearchForm(forms.Form): 
    # lots of fields like this 
    bodystyle = forms.ChoiceField(choices=bodystyle_choices()) 

प्रत्येक विकल्प उदा है ("सैलून", "सैलून (15 कारें)")। तो विकल्पों को इस समारोह द्वारा गणना की जाती है।

def bodystyle_choices(): 
    return [(bodystyle.bodystyle_name, '%s (%s cars)' % 
      (bodystyle.bodystyle_name, bodystyle.car_set.count())) 
      for bodystyle in Bodystyle.objects.all()] 

मेरी समस्या यह है कि हर बार जब मैं केवल my_forms.py आयात करता हूं तो विकल्प कार्य निष्पादित होते जा रहे हैं। मुझे लगता है कि यह जिस तरह से Django अपने खेतों की घोषणा करता है: कक्षा में लेकिन कक्षा विधि में नहीं। जो ठीक है लेकिन मेरे views.py my_forms.py आयात करता है, इसलिए प्रत्येक लुकअप पर विकल्प लुकअप किए जाते हैं चाहे कोई भी दृश्य उपयोग न हो।

मैंने सोचा था कि शायद कोई ब्रैकेट काम करेगा के साथ विकल्प = bodystyle_choices डाल, लेकिन मैं मिलता है:

'function' object is not iterable

जाहिर है मैं कैशिंग का उपयोग करें और "आयात my_forms" सिर्फ आवश्यक दृश्य कार्यों में डाल सकता है, लेकिन जो ऐसा नहीं करता मुख्य बिंदु बदलें: मेरे विकल्पों को आलसी होना चाहिए!

उत्तर

43

आप "सुस्त" समारोह :)

from django.utils.functional import lazy 

class CarSearchForm(forms.Form): 
    # lots of fields like this 
    bodystyle = forms.ChoiceField(choices=lazy(bodystyle_choices, tuple)()) 

बहुत अच्छा util फ़ंक्शन का उपयोग कर सकते हैं!

from django.forms import ModelChoiceField 

class BodystyleChoiceField(ModelChoiceField): 
    def label_from_instance(self, obj): 
     return '%s (%s cars)' % (obj.bodystyle_name, obj.car_set.count())) 

class CarSearchForm(forms.Form): 
    bodystyle = BodystyleChoiceField(queryset=Bodystyle.objects.all()) 

डॉक्स यहाँ हैं: https://docs.djangoproject.com/en/1.8/ref/forms/fields/#modelchoicefield

यह लाभ यह है कि form.cleaned_data['bodystyle'] एक Bodystyle उदाहरण एक के बजाय है

+1

निश्चित रूप से बेहतर समाधान, यह स्वीकार्य उत्तर आईएमओ होना चाहिए। –

+1

/सहमत है कि अब तक मैंने देखा है कि सबसे साफ समाधान है और यह आपको ModelChoiceField से एक महत्वपूर्ण अंतर मान्यताओं के साथ समस्याओं को छोड़ने देता है। – Hassek

+7

यह कम से कम Django 1.6 के साथ काम नहीं करता है, क्योंकि 'ChoiceField._set_choices'' self._choices = self.widget.choices = list (value) ' – spookylukey

18

एक साधारण चॉइसफ़िल्ल्ड के बजाय मॉडलChoiceField का उपयोग करने का प्रयास करें। मुझे लगता है कि आप अपने मॉडल को थोड़ा-सा बदलकर जो चाहते हैं उसे प्राप्त करने में सक्षम होंगे। अधिक के लिए docs पर एक नज़र डालें।

मैं भी जोड़ना होगा कि ModelChoiceFields डिफ़ॉल्ट :) द्वारा lazy हैं

0

क्या Baishampayan घोष ने कहा कि विस्तार करते हुए, यह शायद सबसे सीधा दृष्टिकोण विचार किया जाना चाहिए स्ट्रिंग।

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