2010-08-05 12 views
110

Tengo problemas para tratar de entender cómo crear un campo de elección dinámica en django. Tengo un modelo creado algo como:Creando un campo de elección dinámica

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 whos elección de campo valores son los puntos de referencia asociados con ese piloto (que sería la persona que ha iniciado sesión).

Actualmente estoy preponderantes con init en mis formas, 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 la lista de todos los puntos de ruta, que no están asociados con ningún piloto en particular. ¿Algunas ideas? Gracias.

Respuesta

163

puede filtrar los puntos de ruta pasando el usuario al formulario de inicio

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 punto de vista mientras se inicia el formulario pasan al usuario

form = waypointForm(user) 

en el caso de la 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 
+16

Use ModelChoiceField si es o no un ModelForm, también funciona en formularios normales. –

+8

¿Qué haces cuando quieres obtener los datos de la solicitud? waypointForm (request.POST) no se validará en el primero, porque los datos para validar ya no están allí. – Breedly

+1

@Ashok ¿Cómo podría usarse el widget CheckboxSelectMultiple en esta instancia? Para la forma de modelo especialmente. – wasabigeek

8

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

Generalmente, siempre vale la pena tratar de 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.

4

¿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) 
7

el problema es cuando lo hace

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, se pierde el valor anterior!

1

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

un poco diferente, pero todavía imperfecta, manera de resolver esto 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.

0

Debajo de la solución de trabajo con campo de opción normal. mi problema era que cada usuario tiene sus propias opciones de campo de elección CUSTOM basadas en unas 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 
Cuestiones relacionadas