Creando un campo de elección dynamic

Tengo algunos problemas para entender cómo crear un campo de elección dynamic en django. Tengo un modelo configurado algo como:

class rider(models.Model): user = models.ForeignKey(User) waypoint = models.ManyToManyField(Waypoint) class Waypoint(models.Model): lat = models.FloatField() lng = models.FloatField() 

Lo que estoy tratando de hacer es crear un campo de selección cuyos valores son los puntos de ruta asociados con ese usuario (que sería la persona que inició sesión).

Actualmente estoy sobrescribiendo init en mis formularios así:

 class waypointForm(forms.Form): def __init__(self, *args, **kwargs): super(joinTripForm, self).__init__(*args, **kwargs) self.fields['waypoints'] = forms.ChoiceField(choices=[ (o.id, str(o)) for o in Waypoint.objects.all()]) 

Pero todo lo que hace es enumerar todos los puntos de ruta, no están asociados con ningún jinete en particular. ¿Algunas ideas? Gracias.

puede filtrar los puntos de paso pasando el usuario al formulario init

 class waypointForm(forms.Form): def __init__(self, user, *args, **kwargs): super(waypointForm, self).__init__(*args, **kwargs) self.fields['waypoints'] = forms.ChoiceField( choices=[(o.id, str(o)) for o in Waypoint.objects.filter(user=user)] ) 

Desde tu vista mientras inicias el formulario pasa al usuario.

 form = waypointForm(user) 

en caso de forma modelo

 class waypointForm(forms.ModelForm): def __init__(self, user, *args, **kwargs): super(waypointForm, self).__init__(*args, **kwargs) self.fields['waypoints'] = forms.ModelChoiceField( queryset=Waypoint.objects.filter(user=user) ) class Meta: model = Waypoint 

Hay una solución integrada para su problema: ModelChoiceField .

En general, siempre vale la pena intentar usar ModelForm cuando necesita crear / cambiar objetos de base de datos. Funciona en el 95% de los casos y es mucho más limpio que crear su propia implementación.

el problema es cuando lo haces

 def __init__(self, user, *args, **kwargs): super(waypointForm, self).__init__(*args, **kwargs) self.fields['waypoints'] = forms.ChoiceField(choices=[ (o.id, str(o)) for o in Waypoint.objects.filter(user=user)]) 

en una solicitud de actualización, el valor anterior se perderá!

¿Qué hay de pasar la instancia del usuario al formulario mientras se inicializa?

 class WaypointForm(forms.Form): def __init__(self, rider, *args, **kwargs): super(joinTripForm, self).__init__(*args, **kwargs) qs = rider.Waypoint_set.all() self.fields['waypoints'] = forms.ChoiceField(choices=[(o.id, str(o)) for o in qs]) # In view: rider = request.user form = WaypointForm(rider) 

Debajo de la solución de trabajo con campo de elección normal. Mi problema fue que cada usuario tiene sus propias opciones de campo de elección PERSONALIZADAS basadas en pocas condiciones.

 class SupportForm(BaseForm): affiliated = ChoiceField(required=False, label='Fieldname', choices=[], widget=Select(attrs={'onchange': 'sysAdminCheck();'})) def __init__(self, *args, **kwargs): self.request = kwargs.pop('request', None) grid_id = get_user_from_request(self.request) for l in get_all_choices().filter(user=user_id): admin = 'y' if l in self.core else 'n' choice = (('%s_%s' % (l.name, admin)), ('%s' % l.name)) self.affiliated_choices.append(choice) super(SupportForm, self).__init__(*args, **kwargs) self.fields['affiliated'].choices = self.affiliated_choice 

Como señalaron Breedly y Liang, la solución de Ashok evitará que obtengas el valor de selección al publicar el formulario.

Una forma de resolver ligeramente diferente, pero aún imperfecta, sería:

 class waypointForm(forms.Form): def __init__(self, user, *args, **kwargs): self.base_fields['waypoints'].choices = self._do_the_choicy_thing() super(waypointForm, self).__init__(*args, **kwargs) 

Esto podría causar algunos problemas de concurrencia, sin embargo.