Ich habe einige Probleme zu verstehen, wie man ein dynamisches Auswahlfeld in Django erstellt. Ich habe ein Modell wie folgt eingerichtet:
class rider(models.Model):
user = models.ForeignKey(User)
waypoint = models.ManyToManyField(Waypoint)
class Waypoint(models.Model):
lat = models.FloatField()
lng = models.FloatField()
Ich versuche, ein Auswahlfeld zu erstellen, dessen Werte die Wegpunkte sind, die diesem Fahrer zugeordnet sind (was die angemeldete Person wäre).
Derzeit überschreibe ich init in meinen Formularen wie folgt:
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 es werden nur alle Wegpunkte aufgelistet, sie sind keinem bestimmten Fahrer zugeordnet. Irgendwelche Ideen? Danke.
Aschok
Sie können die Wegpunkte filtern, indem Sie den Benutzer an das Formular init übergeben
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 beim Initiieren des Formulars an den Benutzer übergeben
form = waypointForm(user)
bei Musterform
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
Verwenden Sie ModelChoiceField unabhängig davon, ob es sich um eine ModelForm handelt oder nicht – es funktioniert auch mit normalen Formularen.
– Daniel Rosemann
6. August 10 um 8:02 Uhr
Was machen Sie aber, wenn Sie die Anfragedaten rausholen wollen? waypointForm(request.POST) wird im ersten nicht validiert, da die zu validierenden Daten nicht mehr vorhanden sind.
– Zügig
20. Dezember 13 um 18:48 Uhr
@Ashok Wie könnte das CheckboxSelectMultiple-Widget in diesem Fall verwendet werden? Für die Modellform besonders.
– wasabigeek
14. August 15 um 18:22 Uhr
Wenn Sie die verwenden möchten CheckboxSelectMultiple Widget mit diesem, das Sie verwenden möchten MultipleChoiceField oder ModelMultipleChoiceField. Zunächst scheint es mit zu funktionieren ChoiceFieldaber die Interna werden beschädigt, wenn Sie versuchen, das Formular zu speichern.
– Coredump-Fehler
18. Mai 16 um 0:42 Uhr
Danke @CoreDumpError – habe gerade fast 2 Stunden damit gekämpft, bevor ich deinen Kommentar gelesen habe (doh!) Und das hat endlich alles funktioniert. Andere, achten Sie darauf, Ihre Formularübermittlung (Unicode-Probleme) zu unterbrechen, wenn Sie vorhaben, die zu verwenden CheckboxSelectMultiple Widget mit diesem Code. Wechseln Sie unbedingt ChoiceForm zu MultipleChoiceForm
– also fliege
4. August 16 um 19:25 Uhr
Alexander Lebedew
Es gibt eine integrierte Lösung für Ihr Problem: ModelChoiceField.
Im Allgemeinen lohnt es sich immer, es zu verwenden ModelForm wenn Sie Datenbankobjekte erstellen/ändern müssen. Funktioniert in 95 % der Fälle und ist viel sauberer als das Erstellen einer eigenen Implementierung.
Liang
Das Problem ist, wann Sie es 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)])
bei einem Update-Request geht der vorherige Wert verloren!
Wie wäre es, wenn Sie die Reiterinstanz beim Initialisieren an das Formular ü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)
Darunter Arbeitslösung mit normalem Wahlfeld. Mein Problem war, dass jeder Benutzer seine eigenen BENUTZERDEFINIERTEN Auswahlfeldoptionen hat, die auf wenigen Bedingungen basieren.
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
Genau das, wonach ich gesucht habe! Danke!
– Raubvogel
25. März 18 um 5:57 Uhr
das hat mein Leben einfacher gemacht.. Vielen Dank.. 🙂
– Aravind R. Pillai
9. November 18 um 18:32 Uhr
Zacken
Sie können das Feld als erstklassiges Attribut Ihres Formulars deklarieren und die Auswahl einfach dynamisch festlegen:
class WaypointForm(forms.Form):
waypoints = forms.ChoiceField(choices=[])
def __init__(self, user, *args, **kwargs):
super().__init__(*args, **kwargs)
waypoint_choices = [(o.id, str(o)) for o in Waypoint.objects.filter(user=user)]
self.fields['waypoints'].choices = waypoint_choices
Sie können auch ein ModelChoiceField verwenden und das Abfrageset auf ähnliche Weise auf init setzen.
Genau das, wonach ich gesucht habe! Danke!
– Raubvogel
25. März 18 um 5:57 Uhr
das hat mein Leben einfacher gemacht.. Vielen Dank.. 🙂
– Aravind R. Pillai
9. November 18 um 18:32 Uhr
Reinout van Rees
Wie von Breedly und Liang angegeben, verhindert die Lösung von Ashok, dass Sie beim Senden des Formulars den Auswahlwert erhalten.
Ein etwas anderer, aber immer noch unvollkommener Lösungsweg wäre: