erzeugt "objects.filter" selbstständig Instanzen?

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

Ich kann als Lehrer meine Schülerinnen und Schüler in Lerngruppen gruppieren.
Wenn ich mein Rechenduell aufrufe, werden diese zusätzlich in der Tabelle "Duellant" gruppiert.
Beim ersten Aufruf des Duells ist diese Tabelle leer. Dies möchte ich nutzen, um eine Einstellung in meinem Profil vornehmen. Aber wenn ich in meinem view den Code

Code: Alles auswählen

    duellanten = Duellant.objects.filter(profil__gruppe=gruppe_id)
ausführe, werden anscheinend alle Schülerinnen und Schüler aus der Gruppe automatisch in der Gruppe "Duellant" angelegt. Vorher ist sie leer, nach dem Aufruf sind alle Kids drin. Macht Dajngo das automatisch ohne "create"? Kann ich "create" hier ergänzen um zu überprüfen, dass dies neu erzeugt wird?
Benutzeravatar
sparrow
User
Beiträge: 4501
Registriert: Freitag 17. April 2009, 10:28

Ich werde aus deiner Beschreibung nicht schlau.
Da wird nichts angelegt.

Und du schreibst etwas davon, dass "Duellanten" vorher leer ist. Dann kann hier auch nichts gefiltert werden.
Falls du dort Instanzen erhälst, ist die Tabelle nicht leer.
Pitwheazle
User
Beiträge: 1050
Registriert: Sonntag 19. September 2021, 09:40

Ich kann das gesamte Duell mit allen Einträgen löschen (dazu habe ich einen view).

Code: Alles auswählen

       def duell_loeschen(req):
    gruppe = Lerngruppe.objects.get(pk = req.session.get('gruppe_id'))
    gruppen = Lerngruppe.objects.filter(lehrer=req.user)
    if gruppe.lehrer != req.user:
        return HttpResponse("Zugriff verweigert")
    try:    
        duellanten = Duellant.objects.filter(profil__gruppe = gruppe)
    except:
        messages.error(req, "Diese Duellgruppe existiert nicht")        
        return render(req, 'lehrer/meine_gruppen.html', context={'gruppen': gruppen,})        
    if req.method == 'POST':
        nur_punkte = req.POST.get('nur_punkte', 'off') 
        bestaetigt = req.POST.get('bestaetigt', 'off')
        if bestaetigt == "on":
            if nur_punkte == "on":
...
            else:
                duellanten.all().delete()
        else:
            messages.error(req, "Löschen wurde abgebrochen!")
        return render(req, 'lehrer/meine_gruppen.html', context={'gruppen': gruppen,})
    return render(req, 'duell_loeschen.html' , context={'titel': "Duellgruppe löschen", 'gruppe' : gruppe}) 
Wenn ich den ausführe und im Admintool kontrolliere gibt es keine Duellanten mehr.
Wenn ich aber das Duell neu starte mit:

Code: Alles auswählen

def duell_uebersicht(req, gruppe_id):
    gruppe = get_object_or_404(Lerngruppe, pk=gruppe_id)
    if gruppe.lehrer != req.user and not req.user.is_superuser:
        return HttpResponse("Zugriff verweigert")
    profil = get_object_or_404(Profil, user=req.user)
    profil.duell_gruppe = gruppe_id
    profil.save() 
    duellanten = Duellant.objects.filter(profil__gruppe=gruppe_id)
    for duellant in duellanten:
        duellant.punkte +=duellant.punkte_spiel
        duellant.punkte_spiel = 0
        if duellant.spiele != 0:
            duellant.pps = duellant.punkte/duellant.spiele
        duellant.save()
    schueler_liste = Profil.objects.filter(gruppe=gruppe).order_by("user__profil__vorname")
    for schueler in schueler_liste:
        duellant, created = Duellant.objects.get_or_create(profil = schueler)
        if created:
            duellant.name = schueler.vorname
            duellant.save()
    dubletten = duellanten.values('name').annotate(dubletten=Count('name')).filter(dubletten__gt=1)
    dubletten_liste = []
    if not dubletten:
        pass
    else:
        for dublette in dubletten:
            dubletten_liste.append(dublette["name"])
    leerstellen_liste = []
    for duellant in duellanten:
        if " " in duellant.name:
            leerstellen_liste.append(duellant.name)
    duellanten = duellanten.filter(profil__gruppe = gruppe).order_by("liga", "platz", "profil")
    duell_rang(gruppe.id)
    if req.method == 'POST': 
        IDs = list(req.POST.getlist('ID'))
        for duellant in duellanten:
            duellant.abwesend = True if str(duellant.id) in IDs else False
            duellant.save()
    req.session['gruppe_id'] = gruppe_id  
    context={'gruppe_id': gruppe_id, 'gruppe': gruppe, 'duellanten': duellanten, 'dubletten_liste': ", ".join(dubletten_liste), 'leerstellen_liste': ", ".join(leerstellen_liste),'titel': "Schülerdaten ändern"} 
    return render(req, 'duell_uebersicht.html', context)
... sind alle aus der Gruppe wieder da.
Benutzeravatar
sparrow
User
Beiträge: 4501
Registriert: Freitag 17. April 2009, 10:28

Warum bist du überrascht? In dem View erstellst du die doch?
Pitwheazle
User
Beiträge: 1050
Registriert: Sonntag 19. September 2021, 09:40

Das war meine Frage - mit

Code: Alles auswählen

duellanten = Duellant.objects.filter(profil__gruppe=gruppe_id)
filtert man also nicht nur eine bestehende, man erstellt sie auch (wenn sie noch leer ist)? Ich bräuchte eine Möglichkeit darauf zuzugreifen wenn sie erstellt und nicht aus einer bestehenden gefiltert wird.
Pitwheazle
User
Beiträge: 1050
Registriert: Sonntag 19. September 2021, 09:40

... also "filter_or_create" oder so
Benutzeravatar
sparrow
User
Beiträge: 4501
Registriert: Freitag 17. April 2009, 10:28

Ich schrieb doch bereits oben, dass in der Zeile nichts erstellt wird.
Ich weiß auch gar nicht, wie du darauf kommst.
Im Zweifelsfall könnte man ja auch mal Zeile für Zeile ausgeben lassen, wann sich etwas ändert.

Was macht denn wohl diese Zeile hier?

Code: Alles auswählen

duellant, created = Duellant.objects.get_or_create(profil = schueler)
Pitwheazle
User
Beiträge: 1050
Registriert: Sonntag 19. September 2021, 09:40

Dann habe ich was missverstanden - hier schreibst du doch, hier würde was erstellt:
sparrow hat geschrieben: Freitag 9. August 2024, 20:09 Warum bist du überrascht? In dem View erstellst du die doch?
Benutzeravatar
sparrow
User
Beiträge: 4501
Registriert: Freitag 17. April 2009, 10:28

Ja, wird ja auch.
Aber halt nicht in der Zeile, auf der du dich aufhängst.
Wie gesagt. Schreibt doch mal nach jeder Zeile ein Statement, das die Einträge zählt und guck mal, wann wirklcih welche auftauchen.
Pitwheazle
User
Beiträge: 1050
Registriert: Sonntag 19. September 2021, 09:40

Spannend: Wie macht man das?
Pitwheazle
User
Beiträge: 1050
Registriert: Sonntag 19. September 2021, 09:40

sparrow hat geschrieben: Freitag 9. August 2024, 21:57 Was macht denn wohl diese Zeile hier?

Code: Alles auswählen

duellant, created = Duellant.objects.get_or_create(profil = schueler)
OK - da war ich wieder blind. Aber trotzdem - wie erzeugt man in jeder Zeile ein Statement?
Benutzeravatar
sparrow
User
Beiträge: 4501
Registriert: Freitag 17. April 2009, 10:28

Offensichtlich war deine Annahme aus dem ersten Post ja falsch. Du hast geraten statt das zu prüfen.
Ein einfaches

Code: Alles auswählen

print(f"Anzahl: {Duellant.objects.all().count()}")
in der Zeile danach hätte dir Gewisseheit gebracht.
Und wenn da 0 steht und am Ende der Funktion 50 Trillionen, dann musst du so lange print-Statements in den Code setzen, bis du die Stelle findest, in der das Verhalten auftritt.
Pitwheazle
User
Beiträge: 1050
Registriert: Sonntag 19. September 2021, 09:40

Na, das ist ja gar keine Geheimwissenschaft - einfach "print()"!
Und mein Problem habe ich mit

Code: Alles auswählen

    duellanten = Duellant.objects.filter(profil__gruppe=gruppe_id)
    if duellanten.count() == 0:
         mach was nötig

gelöst. Wieder mal herzlichen Dank für deine/eure Geduld!
Benutzeravatar
Kebap
User
Beiträge: 760
Registriert: Dienstag 15. November 2011, 14:20
Wohnort: Dortmund

Pitwheazle hat geschrieben: Freitag 9. August 2024, 22:23 Na, das ist ja gar keine Geheimwissenschaft - einfach "print()"!
Print Debugging ist super, mach ich heute noch regelmäßig!

Eine andere Art ist, den Python Code im interaktiven Editor so oder möglichst schon vereinfacht Zeile für Zeile einzugeben. Dann kann man nach jeder Zeile in Ruhe weitere Befehle eingeben, sich Objekte genauer anschauen und prüfen, usw.

Das vermisse ich bei anderen Programmiersprachen regelmäßig.
MorgenGrauen: 1 Welt, 8 Rassen, 13 Gilden, >250 Abenteuer, >5000 Waffen & Rüstungen,
>7000 NPC, >16000 Räume, >200 freiwillige Programmierer, nur Text, viel Spaß, seit 1992.
Benutzeravatar
Dennis89
User
Beiträge: 1503
Registriert: Freitag 11. Dezember 2020, 15:13

Hallo,

wenn ich mir zur Fehlersuche etwas ausgeben lassen will, dann finde ich von `icecream` `ic()` viel einfacher als `print`.

https://github.com/gruns/icecream

Grüße
Dennis
"When I got the music, I got a place to go" [Rancid, 1993]
Pitwheazle
User
Beiträge: 1050
Registriert: Sonntag 19. September 2021, 09:40

Ich habe gestern erst die Möglichkeiten kennengelernt im debugg von Firefox zu kontrollieren was da so passeirt.
Antworten