widgets update formularios form fields example ejemplos bootstrap avanzados python django django-forms django-templates

python - update - Creando un campo de elección dinámico



formularios avanzados django (6)

Tengo problemas para tratar de comprender cómo crear un campo de elección dinámica en django. Tengo un modelo configurado algo así 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 intento hacer es crear una opción Campo cuyos valores son los puntos de ruta asociados con ese usuario (que sería la persona que inició sesión).

Actualmente estoy anulando init en mis formularios de esta manera:

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 waypoints, no están asociados con ningún corredor en particular. ¿Algunas ideas? Gracias.


¿Qué tal pasar la instancia del piloto al formulario al inicializarlo?

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)


Como señalan Breedly y Liang, la solución de Ashok le impedirá obtener el valor seleccionado al publicar el formulario.

Una manera ligeramente diferente, pero aún imperfecta, de resolver eso 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)

Sin embargo, esto podría causar algunos problemas de concurrencia.


Debajo de la solución de trabajo con el campo de elección normal. Mi problema es que cada usuario tiene sus propias opciones de campo de elección CUSTOM basadas en algunas 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


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

En general, siempre vale la pena tratar de usar ModelForm cuando necesite 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á!


puede filtrar los puntos de referencia pasando al 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 su vista al iniciar el formulario, pase al usuario

form = waypointForm(user)

en caso de forma de 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