Darstellung der Auswahl über Filter

Django, Flask, Bottle, WSGI, CGI…
Antworten
Pitwheazle
User
Beiträge: 869
Registriert: Sonntag 19. September 2021, 09:40

Auf der Protokollseite kann man auswählen, ob alle Aufgaben oder nur die von der Woche oder dem Tag angezeigt werden:
Bild
Am liebsten wäre es mir, wenn nach der Auswahl, diese Auswahl angezeigt würde, diese Anzeige springt aber immer auf "nächstes Halbjahr".
Da ich das nicht hinbekommen habe, lasse ich den Filter untendrunter anzeigen. Da steht jetzt aber z.B. "all", wie lasse ich anstelle dessen den human_readible Wert "Alle Aufgaben" anzeigen?
forms:

Code: Alles auswählen

class ProtokollFilter_neu(forms.Form):
    filter = forms.ChoiceField(label='Filter', choices=[("next",'nächstes Halbjahr'), ("Halbjahr",'aktuelles Halbjahr'), ('heute','heute'), ('Woche','Woche'), ("Schuljahr",'aktuelles Schuljahr'),("all",'Alle Aufgaben'),])
 
template:

Code: Alles auswählen

<th>{{filter}}</th>
view:

Code: Alles auswählen

def protokoll(req):
    if req.user.is_authenticated: 
        user = get_user(req.user) 
        protokoll = Protokoll.objects.filter(user=user).order_by('id').reverse()
        filter = "Alle Aufgaben"
        sj, hj = name_hj()
        ...
        form = ProtokollFilter_neu
        if req.method == 'POST':
            protokoll = Protokoll.objects.filter(user=user).order_by('id').reverse()
            auswahl = form(req.POST)
            if auswahl.is_valid(): 
                filter = auswahl.cleaned_data['filter']
                if filter == "next":
                   protokoll = protokoll.filter(sj=next_sj, hj=next_hj)  
                if filter == "Halbjahr":
                    protokoll = protokoll.filter(sj=sj, hj=hj)                               
...
        return render(req, 'core/protokoll.html', {'protokoll': protokoll, 'form': form, 'filter': filter, ...})
Benutzeravatar
noisefloor
User
Beiträge: 3843
Registriert: Mittwoch 17. Oktober 2007, 21:40
Wohnort: WW
Kontaktdaten:

Hallo,

ich verstehe das Problem nicht (vielleicht, weil das Bild fehlt)... Wie wird wo was (nicht) angezeigt?

`filter` ist ein schlechter Name für deine Variablenzuweisung, weil du damit die Python Built-in Funktion namens `filter` überschreibst. Kann, muss aber nicht, ungewollte Nebeneffekte haben. Wenn du einen Editor mit Syntaxhervorhebung nutzt sollte das aber auch angezeigt werden.

Gruß, noisefloor
Pitwheazle
User
Beiträge: 869
Registriert: Sonntag 19. September 2021, 09:40

noisefloor hat geschrieben: Donnerstag 3. November 2022, 18:01 ich verstehe das Problem nicht (vielleicht, weil das Bild fehlt)... Wie wird wo was (nicht) angezeigt?
Komisch - bei mir wird es angezeigt. Also nochmal:
in forms gibt es folgende choices:

Code: Alles auswählen

class ProtokollFilter(forms.Form):
    auswahl = forms.ChoiceField(label='Filter', choices=[("Halbjahr",'aktuelles Halbjahr'), ('heute','heute'), ('Woche','Woche'), ("Schuljahr",'aktuelles Schuljahr'),("all",'Alle Aufgaben'),])
und das wird auch wunderbar angezeigt:
Bild

wenn ich aber "Alle Aufgaben" auswähle, bleibt "Alle Aufgaben" nicht stehen (das fände ich ja am Besten, weiß aber nicht, wie das zu bewerkstelligen wäre) und unten wird "all" angezeigt - da hätte ich gerne "Alle Aufgaben":

Bild

Ich habe die "filter" in "auswahl" umbenannt - Ich arbeite mit VisualStudioCode und habe die Syntxhervorhebung installiert - sehe aber keine Probleme.
Benutzeravatar
noisefloor
User
Beiträge: 3843
Registriert: Mittwoch 17. Oktober 2007, 21:40
Wohnort: WW
Kontaktdaten:

Hallo,
wenn ich aber "Alle Aufgaben" auswähle, bleibt "Alle Aufgaben" nicht stehen (das fände ich ja am Besten, weiß aber nicht, wie das zu bewerkstelligen wäre) und unten wird "all" angezeigt - da hätte ich gerne "Alle Aufgaben":
Ach so, du meinst wenn eine Auswahl getroffen wurde, die Seite / das Formular abgeschickt wurde und dann die neue Seite angezeigt wird, richtig?

Bei Auswahlfeldern wird immer nur der Wert des Feldes übertragen. In `choices` stehen Tupel, als erstes der Wert und und als zweites das Label. Das Label dient "nur" zur Anzeige, wird aber beim Absenden des Formular nichts mehr übertragen. D.h. wenn du ein Formalur verarbeitest, darauf basierend eine neue Seite auslieferst und nicht den Wert des Auswahlfelds selber anzeigen willst, sondern was, was dem Wert zu geordnet ist (wie hier all -> Alle Aufgaben) musst du dich selber darum kümmern.

Bzgl. Bilder: die werden bei mir wohl von der Privacy Badger Erweiterung des Firefox weggeblock, weil die wohl Tracking Stufe rot (=kritisch) erlauben. Keine Ahnung, was Dropbox bzw. die eingebundenen Bilder da so treiben.

Gruß, noisefloor
Pitwheazle
User
Beiträge: 869
Registriert: Sonntag 19. September 2021, 09:40

noisefloor hat geschrieben: Freitag 4. November 2022, 06:42 Ach so, du meinst wenn eine Auswahl getroffen wurde, die Seite / das Formular abgeschickt wurde und dann die neue Seite angezeigt wird, richtig?
richtig
noisefloor hat geschrieben: Freitag 4. November 2022, 06:42 Bei Auswahlfeldern wird immer nur der Wert des Feldes übertragen. In `choices` stehen Tupel, als erstes der Wert und und als zweites das Label. Das Label dient "nur" zur Anzeige, wird aber beim Absenden des Formular nichts mehr übertragen. D.h. wenn du ein Formalur verarbeitest, darauf basierend eine neue Seite auslieferst und nicht den Wert des Auswahlfelds selber anzeigen willst, sondern was, was dem Wert zu geordnet ist (wie hier all -> Alle Aufgaben) musst du dich selber darum kümmern.
Dieses Tupel steht ja in forms. Um es an das Template zu schicken, müsste ich dann dieses Tupel also nochmal in mein view übertragen, damit ich es da auswerten kann?
noisefloor hat geschrieben: Freitag 4. November 2022, 06:42 Bzgl. Bilder: die werden bei mir wohl von der Privacy Badger Erweiterung des Firefox weggeblock, weil die wohl Tracking Stufe rot (=kritisch) erlauben. Keine Ahnung, was Dropbox bzw. die eingebundenen Bilder da so treiben.
Habe ich da irgendeinen Einfluss?
Benutzeravatar
noisefloor
User
Beiträge: 3843
Registriert: Mittwoch 17. Oktober 2007, 21:40
Wohnort: WW
Kontaktdaten:

Hallo,
Dieses Tupel steht ja in forms. Um es an das Template zu schicken, müsste ich dann dieses Tupel also nochmal in mein view übertragen, damit ich es da auswerten kann?
Richtig bzw. ich wüßte keinen anderen Weg. Wobei du in View ja eine Instanz deines Formulars hast, d.h. eigentlich müsstest du da dann auch an die `choices` Liste kommen. Müsstest du mal ein bisschen rumprobieren.

Gruß, noisefloor
Benutzeravatar
noisefloor
User
Beiträge: 3843
Registriert: Mittwoch 17. Oktober 2007, 21:40
Wohnort: WW
Kontaktdaten:

Nachtrag:
eigentlich müsstest du da dann auch an die `choices` Liste kommen.
Geht scheinbar doch nicht. Jedenfalls habe ich es nicht geschafft.

Gruß, noisefloor
Pitwheazle
User
Beiträge: 869
Registriert: Sonntag 19. September 2021, 09:40

Ich habe einfach ein entsprechendes dictonary in meinem view gespeichert. Das ist vielleicht nicht so elegant, funktioniert aber prima.
Benutzeravatar
noisefloor
User
Beiträge: 3843
Registriert: Mittwoch 17. Oktober 2007, 21:40
Wohnort: WW
Kontaktdaten:

Nachtrag zum Nachtrag: geht doch.

In deinem Fall sollte folgendes funktionieren:

Code: Alles auswählen

...
if req.method == 'POST':
    protokoll = Protokoll.objects.filter(user=user).order_by('id').reverse()
    auswahl = form(req.POST)
    auswahl2 = form()
    choices = auswahl_raw.fields['auswahl'].choices
    ...
`choices` ist eine Liste vom Listen, die du dann einfach in eine Dict wandeln kannst.

Ob das nicht auch besser / eleganter geht weiß ich nicht. Jedenfalls hast du die `choices` nur an einer Stelle im Code, nämlich in der Form-Klasse.

Gruß, noisefloor
Pitwheazle
User
Beiträge: 869
Registriert: Sonntag 19. September 2021, 09:40

Ich bin ja immer wieder gerührt, dass du/ihr soviel Arbeit in mein Projekt steckt (eigentlich sollte ich es "unser Projekt" nennen!)

Ich bekomme eine Fehlermeldung bei "choices = auswahl_raw.fields['auswahl'].choices":

Code: Alles auswählen

 	
name 'auswahl_raw' is not defined
... und leider habe ich ja auch wieder keine Ahnung wie dieser Code funktioniert ... und auch wofür "auswahl2 = form()" dient :?
Benutzeravatar
noisefloor
User
Beiträge: 3843
Registriert: Mittwoch 17. Oktober 2007, 21:40
Wohnort: WW
Kontaktdaten:

Ups, sorry. Der Code muss so sein:

Code: Alles auswählen

...
if req.method == 'POST':
    protokoll = Protokoll.objects.filter(user=user).order_by('id').reverse()
    auswahl = form(req.POST)
    auswahl2 = form()
    choices = auswahl2.fields['auswahl'].choices
    ...
Aber es geht doch noch einfacher, nämlich:

Code: Alles auswählen

...
if req.method == 'POST':
    protokoll = Protokoll.objects.filter(user=user).order_by('id').reverse()
    auswahl = form(req.POST)
    choices = auswahl.fields['auswahl'].choices
    ...
Spart die Krücke über die `auswahl2`.
Ich bin ja immer wieder gerührt, dass du/ihr soviel Arbeit in mein Projekt steckt
Gerne. 1. lernst du was, 2. lerne ich auch (manchmal) noch was und 3. sind einige deiner Probleme nicht spezifisch für dein Projekt, d.h. die Lösungen können andere in Zukunft auch nutzen.

Gruß, noisefloor
Pitwheazle
User
Beiträge: 869
Registriert: Sonntag 19. September 2021, 09:40

Unglaublich - das funktioniert wirklich!
Pitwheazle
User
Beiträge: 869
Registriert: Sonntag 19. September 2021, 09:40

Nachtrag: Nein, doch nicht ganz. Beim ersten (GET) Aufruf, wähle ich zwar die form, da dies kein "POST" Aufruf ist und diese Liste erst beim Post-Aufruf ausgelesen wird, führt das bei:

Code: Alles auswählen

return render(req, 'core/protokoll.html', {.. 'auswahl': auswahl_liste[auswahl], ...})
zu einem Fehler. "auswahl_liste" erstelle ich mit:

Code: Alles auswählen

            wahl = form(req.POST)
            choices = wahl.fields['auswahl'].choices
            auswahl_liste = dict(choices)
... Ich kann es aber auch einfach bei meinem doppelten dict lassen - es sei denn du hast da sportlichen Ergeiz, mir auch noch zu erklären, wie das mit POST/GET zu lösen ist.
Antworten