Tengo un formulario django con un campo de elección, donde cargo dinámicamente algunas opciones en el campo:
class EntryForm(forms.Form): project = forms.ChoiceField() def __init__(self, *args, **kwargs): user = kwargs.pop('user', None) super(EntryForm, self).__init__( *args, **kwargs) CHOICES2=[] for x in Project.objects.all() : if user in x.users.all(): CHOICES2.append((x.name,x.name)) CHOICES1 = [(x.name,x.name) for x in Project.objects.all()] print CHOICES2==CHOICES1 #this is True in this case self.fields['project']=forms.ChoiceField(choices=CHOICES2)El formulario se carga en la plantilla con {{form.as_table}}. El formulario no muestra un menú desplegable para el campo del proyecto. Ahora lo extraño: si cambio la última línea a:
self.fields['project']=forms.ChoiceField(choices=CHOICES1)funciona, aunque la declaración de impresión de la comparación "=="" devuelve True (las listas son deliberadamente las mismas, esto es solo para probar). Realmente no tengo idea de cómo esto puede funcionar técnicamente.
Editar - mi modelo de proyecto:
class Project(BaseModel): name = models.CharField(max_length=80) users = models.ManyToManyField(User)Creo que debe usar el argumento queryset, que es obligatorio: https://docs.djangoproject.com/en/1.8/ref/forms/fields/#django.forms.ModelChoiceField.queryset
ChoiceField debe declararse con (queryset=None), y en el método __init__ se completa la consulta: https://docs.djangoproject.com/en/1.11/ref/forms/fields/#fields-which-handle-relationships
El problema podría estar relacionado con el orden de ejecución de las consultas o el caché de consultas no perezosas.
Y estoy de acuerdo con little_birdie: el campo ya existe.
Su campo llamado project ya existe y no hay necesidad de construir otro como lo está haciendo. Es mejor establecer las opciones en el campo existente:
self.fields['project'].choices = CHOICES2Pero tal vez sería mejor usar un ModelChoiceField:
project = ModelChoiceField(queryset=Project.objects.none())y luego configure el conjunto de consultas que desea en init así:
self.fields['project'].queryset=Project.objects.filter(users__in=[user]) ..que debería darle una lista de todos los proyectos asociados con user .