Pregunta

Tengo un my_forms.py Django como esto:

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

Cada opción es, por ejemplo ( "Saloon", "salón (15 coches)"). Así que las opciones se calculan por esta función.

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

Mi problema es que las opciones son funciones de la silla eléctrica cada vez que simplemente importar my_forms.py. Creo que esto es debido a la forma de Django declara sus campos: en la clase, pero no en un método de clase. Lo cual está bien, pero mis importaciones views.py my_forms.py por lo que las opciones de búsquedas se realizan en cada petición no importa qué punto de vista se utiliza.

pensé que tal vez poniendo opciones = bodystyle_choices sin soporte quiere trabajar, pero me sale:

'function' object is not iterable

Obviamente, yo puedo utilizar el almacenamiento en caché y poner los "my_forms importación" por si las funciones de vista necesarios, pero eso no cambia el punto principal: mis decisiones tienen que ser perezoso

¿Fue útil?

Solución

Puede utilizar la función de "perezosa":)

from django.utils.functional import lazy

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

muy agradable función util!

Otros consejos

Trate de usar un ModelChoiceField en lugar de un simple ChoiceField. Creo que va a ser capaz de lograr lo que quiere por ajustar sus modelos un poco. Echar un vistazo a la por más.

También me gustaría añadir que ModelChoiceFields se lazy por defecto:)

Ampliando lo Baishampayan Ghose dijo, esto probablemente se debe considerar el enfoque más directo:

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())

Docs están aquí: https://docs.djangoproject.com /en/1.8/ref/forms/fields/#modelchoicefield

Esto tiene la ventaja de que es una instancia de form.cleaned_data['bodystyle'] Bodystyle lugar de una cadena.

Puede ahora sólo tiene que utilizar (ya que creo Django 1.8):

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

Tenga en cuenta que falta el paréntesis. Si tiene que pasar argumentos, acabo de hacer una versión especial de la función con ellos hardcoded sólo para ese formulario.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top