with manually formmodel form fields creating all django forms widget

manually - Opciones dinámicas para Django SelectMultiple Widget



django widget render (2)

Estoy construyendo un formulario (no modelForm) donde me gustaría utilizar el widget SeleccionarMúltiple para mostrar las opciones basadas en una consulta realizada durante el inicio del formulario.

Puedo pensar en algunas formas de hacerlo, pero no estoy del todo claro en el camino correcto para hacerlo. Veo diferentes opciones.

Obtengo las "elecciones" que debería pasar al widget en el formulario init, pero no estoy seguro de cómo debo pasarlas.

class NavigatorExportForm(forms.Form): def __init__(self,user, app_id, *args,**kwargs): super (NavigatorExportForm,self ).__init__(*args,**kwargs) # populates the form language_choices = Navigator.admin_objects.get(id=app_id).languages.all().values_list(''language'', flat=True) languages = forms.CharField(max_length=2, widget=forms.SelectMultiple(choices=???language_choices))


¿Por qué no utilizar un ModelMultipleChoiceField en ModelMultipleChoiceField lugar?

Podrías hacer simplemente esto:

class NavigatorExportForm(forms.Form): languages = forms.ModelMultipleChoiceField(queryset=Language.objects.all()) def __init__(self, app_id, *args, **kwargs): super(NavigatorExportForm, self).__init__(*args, **kwargs) # Dynamically refine the queryset for the field self.fields[''languages''].queryset = Navigator.admin_objects.get(id=app_id).languages.all()

De esta manera, no solo restringe las opciones disponibles en el widget, sino también en el campo (que le da validación de datos).

Con este método, la cadena mostrada en el widget sería el resultado del método __unicode__ en un objeto de Language . Si no es lo que desea, puede escribir el siguiente campo personalizado, como se documenta en la referencia de ModelChoiceField :

class LanguageMultipleChoiceField(forms.ModelMultipleChoiceField): def label_from_instance(self, obj): return obj.language_code # for example, depending on your model

y use esta clase en lugar de ModelMultipleChoiceField en su formulario.


def __init__(self,user, app_id, *args,**kwargs): super (NavigatorExportForm,self ).__init__(*args,**kwargs) self.fields[''languages''].widget.choices = Navigator.admin_objects.get(id=app_id).languages.all().values_list(''language'', flat=True)

eso parece hacer el truco, pero incluso al no especificar max_length, el widget solo muestra la primera letra de las opciones ...