2010-08-05 14 views
110

Ich habe Probleme, zu verstehen, wie ein dynamisches Auswahlfeld in Django erstellt wird. Ich habe ein Modell so etwas wie ein:Erstellen eines dynamischen Auswahlfelds

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

class Waypoint(models.Model): 
    lat = models.FloatField() 
    lng = models.FloatField() 

Was ich versuche ein Auswahlfeld whos Werte die mit dem Fahrer zugeordnet Wegpunkte sind zu tun ist, erstellen (die die Person angemeldet sein würde).

Derzeit bin ich überschreiben init in meine Formen wie so:

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()]) 

Aber alles, was tut, ist die Liste alle Wegpunkte, sie sind nicht mit einem bestimmten Fahrer zugeordnet ist. Irgendwelche Ideen? Vielen Dank.

Antwort

163

können Sie die Wegpunkte filtern, indem Sie den Benutzer auf das Formular init vorbei

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

aus Ihrer Sicht, während das Formular dem Benutzer

form = waypointForm(user) 

bei Modellform passieren Einleitung

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

Verwenden Sie ModelChoiceField, ob es eine ModelForm ist oder nicht - es funktioniert auch auf normalen Formularen. –

+8

Was tun Sie, wenn Sie die Anforderungsdaten abrufen möchten? waypointForm (request.POST) wird in der ersten nicht validiert, da die zu validierenden Daten nicht mehr vorhanden sind. – Breedly

+1

@Ashok Wie könnte das CheckboxSelectMultiple-Widget in diesem Fall verwendet werden? Für die Modellform besonders. – wasabigeek

8

Es gibt eine integrierte Lösung für Ihr Problem: ModelChoiceField.

Im Allgemeinen ist es immer empfehlenswert, ModelForm zu verwenden, wenn Sie Datenbankobjekte erstellen/ändern müssen. Funktioniert in 95% der Fälle und es ist viel sauberer als eine eigene Implementierung zu erstellen.

4

Wie wäre es, die Reiterinstanz während der Initialisierung an das Formular zu übergeben?

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

das Problem ist, wenn Sie

tun
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)]) 

in einer Aktualisierungsanforderung, wird der vorherige Wert verloren!

1

Wie Breedly und Liang zeigen, verhindert die Lösung von Ashok, dass Sie den ausgewählten Wert beim Buchen des Formulars erhalten.

Eine etwas andere, aber immer noch unvollkommen, Art und Weise zu lösen, dass sein würde:

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) 

Dieses einige Zustimmung zu Problemen führen könnte, though.

0

Unter Arbeitslösung mit normalem Auswahlfeld. Mein Problem war, dass jeder Benutzer seine eigenen CUSTOM Choice-Optionen auf der Grundlage von wenigen Bedingungen hat.

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 
Verwandte Themen