Django dynamic choices für Formular

Django, Flask, Bottle, WSGI, CGI…
Antworten
naheliegend
User
Beiträge: 439
Registriert: Mittwoch 8. August 2018, 16:42

Hi,

was ist der einfachste Weg dynamisch (abhängig vom Status des aktuell eingeloggten Users) die Auswahlmöglichkeiten (choices) in einem Form anzuzeigen?

LG
__backjack__: "Jemand der VB oder PHP kann, der also was Programmieren angeht irgendwo im negativen Bereich liegt (...)"
Benutzeravatar
noisefloor
User
Beiträge: 3843
Registriert: Mittwoch 17. Oktober 2007, 21:40
Wohnort: WW
Kontaktdaten:

Hallo,

du kannst das Attribute `choices` des `ChoiceField` nachträglich überschreiben:
>>> from django import forms
>>> f = forms.ChoiceField()
>>> f.choices
[]
>>> f.choices = (('foo', 'foo'), ('bar', 'bar'))
>>> f.choices
[('foo', 'foo'), ('bar', 'bar')]
>>>
Außerdem kennt Django das Formfield ModelChoiceField, mit dem du die `choices` einem Query gegen die DB belegen kannst.

Gruß, noisefloor
naheliegend
User
Beiträge: 439
Registriert: Mittwoch 8. August 2018, 16:42

Danke dir.
noisefloor hat geschrieben: Sonntag 25. April 2021, 19:01 (...)
Außerdem kennt Django das Formfield ModelChoiceField, mit dem du die `choices` einem Query gegen die DB belegen kannst.
Wenn ich den queryset mit einem Query belege kann ich aber nicht dynamisch nach beispielsweise dem aktuellen User filtern, oder?

Sowas zum Beispiel:

Code: Alles auswählen

choice = forms.ModelChoiceField(queryset=Meeting.objects.exclude(
id__in=MeetingParticipant.objects.filter(user=User.id).values_list('meeting', flat=True)), to_field_name="title")
__backjack__: "Jemand der VB oder PHP kann, der also was Programmieren angeht irgendwo im negativen Bereich liegt (...)"
Benutzeravatar
noisefloor
User
Beiträge: 3843
Registriert: Mittwoch 17. Oktober 2007, 21:40
Wohnort: WW
Kontaktdaten:

Hallo,

ich habe das selber noch nie benutzt, aber: Lt. Doku wird der Query erst beim Rendern der Form ausgeführt, d.h. zum dem Zeitpunkt muss (erst) `User.id` aus deinem Beispiel bekannt sein. Damit sollte sich auch was dynamisieren lassen.

Gruß, noisefloor
naheliegend
User
Beiträge: 439
Registriert: Mittwoch 8. August 2018, 16:42

Hm, aber dann müsste ich ja user.id einsetzen für das aktuelle user-objekt. Aber dann meckert er, dass er user.id nicht kennt.
__backjack__: "Jemand der VB oder PHP kann, der also was Programmieren angeht irgendwo im negativen Bereich liegt (...)"
Benutzeravatar
noisefloor
User
Beiträge: 3843
Registriert: Mittwoch 17. Oktober 2007, 21:40
Wohnort: WW
Kontaktdaten:

Hallo,

bei eingeloggten Benutter bekommst du doch den aktuellen User aus dem request-Objekt von Django. Darüber solltest du doch auch an die ID des Users kommen.

Gruß, noisefloor
naheliegend
User
Beiträge: 439
Registriert: Mittwoch 8. August 2018, 16:42

Ich habe das jetzt so gemacht:

views.py

Code: Alles auswählen

choice_list = Meeting.objects.exclude(
        id__in=MeetingParticipant.objects.filter(
        user=request.user.id).values_list('meeting', flat=True)).values_list('id', 'title')
        
form = SelectMeeting(choice_list=choice_list)    

return render(request, "app/forms.html", {"form": form})
Hier war das values_list('id', 'title') wichtig, da ich so eine Liste von Tuples erhalte, weil choices immer noch einen unique Wert erwartet, was hier die 'id' ist.

forms.py

Code: Alles auswählen

class SelectMeeting(forms.Form):

   def __init__(self, choice_list, *args, **kwargs):
        super(SelectMeeting, self).__init__(*args, **kwargs)
        self.fields['choice'].choices = choice_list

   choice = forms.ChoiceField(required=True)     
Die choice_list aus dem View übergebe ich bei der Initialisierung.

Vielleicht gibt es auch einen besseren Weg, aber so funktioniert es.
__backjack__: "Jemand der VB oder PHP kann, der also was Programmieren angeht irgendwo im negativen Bereich liegt (...)"
Antworten