Cómo configurar dinámicamente el queryset de un models.ModelChoiceField en una forma.Corma subclase

El constructor para forms.ModelChoiceField requiere un queryset. No sé el queryset hasta que se produce la solicitud. Destilado:

 # models.py class Bar(models.model): text = models.TextField() class Foo(models.Model): name = models.CharField() bar = models.ForeignKey(Bar) # forms.py class FooForm(forms.Form): name = forms.CharField() text = forms.CharField(widget=forms.TextArea) bar = forms.ModelChoiceField(queryset='??????') 

Lo que estoy haciendo actualmente:

 # forms.py def get_foo_form_class(bars_queryset): class FooForm(forms.Form): name = forms.CharField() text = forms.CharField(widget=forms.TextArea) bar = forms.ModelChoiceField(queryset=bars_queryset) return FooForm 

Entonces puedo llamarlo en la vista usando argumentos analizados fuera de la url con un urlconf para construir el queryset y obtener la clase. Esto se siente como la manera incorrecta de hacerlo. ¿Hay una manera establecida de hacer esto en django?

Reemplace el método __init__ del __init__ y establezca el queryset allí.

 class FooForm(forms.Form): bar = forms.ModelChoiceField(queryset=Bar.objects.none()) def __init__(self, *args, **kwargs): qs = kwargs.pop('bars') super(FooForm, self).__init__(*args, **kwargs) self.fields['bar'].queryset = qs 

También puede hacerlo en su vista antes de presentar el formulario en la plantilla. Lo uso y lo encuentro más flexible en caso de que reutilice el formulario en otras vistas y necesite cambiar el conjunto de consultas cada vez:

 from assets.models import Asset location_id = '123456' edit_form = AsssetSelectForm(request.POST or None, instance=selected_asset) edit_form.fields["asset"].queryset = Asset.objects.filter(location_id=location_id) 

También puse el queryset predeterminado en ninguno en forms.py:

 class AsssetSelectForm(forms.Form): asset = forms.ModelChoiceField(queryset=Asset.objects.none())