Seite 1 von 2
Änderungen in Template
Verfasst: Donnerstag 11. Juli 2024, 13:50
von Pitwheazle
Ich sitze jetzt an meinem Rechenduell. Dafür habe ich ein model und ein Template erstellt. Das sieht jetzt so aus:

Die Lehrkraft müsste in der letzten Spalte das Feld anklicken können, falls der/die Schüler/in krank oder anderweitig verhindert ist und am Duell nicht teilnehmen kann. Außerdem muss die Lehrkraft vor dem ersten Duell die Schülerinnen und Schüler in Ligen einteilen können (Eintrag in der ersten Spalte). Ich weiß nicht so recht, wie ich das bewerkstelligen kann. Forms passt hier nach meiner Einschätzung nicht, da ich damit ja nur einzelne Einträge in der Datenbank anlegen bzw. ändern kann - nicht aber Einträge für alle Schülerinnen und Schüler einer Gruppe - oder sehe ich das falsch?
Geht das überhaupt, dass ich aus diesem Template Änderungen vornehme?
Mein model:
.
Code: Alles auswählen
class Duell(models.Model):
profil = models.OneToOneField(Profil, related_name='duellprofil', on_delete=models.CASCADE)
gruppe = models.ForeignKey(Lerngruppe, null= True, blank=True, on_delete = models.CASCADE, related_name='duellgruppe')
liga = models.CharField(max_length=1, default="A")
platz = models.SmallIntegerField(null=True, blank=True)
aufsteiger = models.BooleanField(default=False)
abwesend = models.BooleanField(default=False)
spiele = models.SmallIntegerField(default=0)
punkte = models.DecimalField(max_digits=3, decimal_places=1, default=0)
pps = models.DecimalField(max_digits=4, decimal_places=2, default=0)
und mein Template:
Code: Alles auswählen
...
<body>
<div class="container">
<table>
<thead>
<tr>
<th >Liga</th>
<th >↑</th>
<th >Platz</th>
<th width= "200px">Name</th>
<th >Spiele</th>
<th >Punkte</th>
<th >PPS</th>
<th >*</th>
</tr>
</thead>
<tbody>
</tr>
{% for zeile in duell_liste %}
<tr class = {{zeile.liga}}>
<td>{{zeile.liga}}</td>
<td>{% if zeile.aufsteiger %}*{%else%}{%endif%}</td>
<td>{% if zeile.platz %}{{zeile.platz}}{%else%}{%endif%}</td>
<td style="text-align: left";>{{zeile.profil.vorname}} {{zeile.profil.nachname|slice:"30"}}</td>
<td>{{zeile.spiele}}</td>
<td>{{zeile.punkte}}</td>
<td>{{zeile.pps}}</td>
<td>{% if zeile.abwesend %}*{%else%}{%endif%}</td>
</tr>
{% empty %}
<tr><td colspan="999"><strong>Es sind noch keine Schüler angemeldet.</strong></td></tr>
{% endfor %}
</tbody>
</table>
</div>
</body>
der/die/das view:
Code: Alles auswählen
def duell(req, gruppe_id):
gruppe = get_object_or_404(Lerngruppe, pk=gruppe_id)
titel = f"{gruppe.name}, {gruppe.lehrer.profil.vorname} {gruppe.lehrer.profil.nachname}"
schueler_liste = Profil.objects.filter(gruppe__name=gruppe.name).order_by("user__profil__vorname")
for schueler in schueler_liste:
duell, created = Duell.objects.get_or_create(profil = schueler, gruppe = gruppe)
duell_liste = Duell.objects.filter(gruppe=gruppe).order_by("liga", "platz", "profil")
context={'gruppe': gruppe.name,'duell_liste': duell_liste}
return render(req, 'lehrer/rechenduell.html', context)
Re: Änderungen in Template
Verfasst: Donnerstag 11. Juli 2024, 15:23
von grubenfox
Was gibt den HTML so her an Dingen die anklickbar sind? Das muss dann in das Feld der der letzten Spalte. So ein einsames * ist ja nicht anklickbar....
Re: Änderungen in Template
Verfasst: Donnerstag 11. Juli 2024, 17:46
von Pitwheazle
Hallo @grubenfox Vielen Dank für den Hinweis. Ich bin mir bewusst, dass ich nur kleine Teile von Django, HTML, CSS und Phyton beherrsche und bin dir auch wirklich immer dankbar für deine Tipps - dieser Post ist aber schon arg überheblich.
Hätte ja sein können, dass es bei Django eine Möglichkeit gibt, mittels Forms eine Auswahl von Instanzen gleichzeitig zu bearbeiten. Ich entnehme deiner Antwort, dass dem nicht so ist und werde mich auf die Suche nach anklickbaren HTML Dingen zu machen (die hatte ich noch nicht - oder weiß es nicht mehr).
Re: Änderungen in Template
Verfasst: Donnerstag 11. Juli 2024, 18:39
von noisefloor
Hallo,
IMHO ist der Entwurf grundlegend falsch und es fehlt ein bisschen Kontext, um es besser machen zu können. Wie soll denn das Quiz konkret aussehen. Aktuell wissen wir ja "nur", wie es in LibreOffice Calc aussah - aber nicht, wie es jetzt in deiner Webanwendung aussehen soll.
Reicht es nicht, wenn du:
1. eine Liste von Schülern in der Klasse X erstellst - die Daten sind ja in der DB.
2. dem Lehrer die Möglichkeit gibt, Leute abzuwählen (weil nicht anwesend) oder in eine Gruppe A/B/C/... einzuteilen.
3. die Daten _temporär_ im Speicher zu halten (Django hat ein Cache-Framework)
4. das Quiz durchzuführen
5. das _Ergebnis_ in einer eigenen Tabelle zu speichern
2. geht mit einem Formular. Deine Einschätzung "Forms passt hier nach meiner Einschätzung nicht, da ich damit ja nur einzelne Einträge in der Datenbank anlegen bzw. ändern kann" ist komplett falsch. Das kann man zwar auch mit Formularen machen - aber du kannst auch alles andere damit machen. Es zwingt dich niemand, ein Formular an ein Modell zu knüpfen.
_Persönlich_ finde ich, basierend aus der Erfahrung mit K2 (8. Klasse Gynasium in RLP) und dem Unterricht dort, deinen kompetitiven Ansatz mit der plakativen Einteilung in (Leistungs-) Klassen für... schwierig. Schwierig von didaktisch fragwürdig im Jahr 2024. Aber das ist letztendlich deine Entscheidung, wie du das implementierst.
Gruß, noisefloor
Re: Änderungen in Template
Verfasst: Donnerstag 11. Juli 2024, 19:15
von noisefloor
Nachtrag, um Missverständnisse zu vermeiden: die Kernaufaufgabe von Djangos Cache Framework ist das Caching von ganzen Seiten. Man kann die Low-Level API des Frameworks aber auch benutzen, im Daten über mehrere Requests hinweg temporär zu speichern. Geht aber wahrscheinlich auch anders.
Gruß, noisefloor
Re: Änderungen in Template
Verfasst: Donnerstag 11. Juli 2024, 21:02
von Pitwheazle
Hallo @noisefloor erstmal Dank, dass du dich mit meinem Problem beschäftigst. Aber einiges in deinem Post verstehe ich nicht so ganz
noisefloor hat geschrieben: Donnerstag 11. Juli 2024, 18:39
_Persönlich_ finde ich, basierend aus der Erfahrung mit K2 (8. Klasse Gynasium in RLP) und dem Unterricht dort, deinen kompetitiven Ansatz mit der plakativen Einteilung in (Leistungs-) Klassen für... schwierig. Schwierig von didaktisch fragwürdig im Jahr 2024. Aber das ist letztendlich deine Entscheidung, wie du das implementierst.
Ich bin (oder besser war) Lehrer an einer integrierten Gesamtschule und dort haben wir nunmal Leistungskurse in Mathe. Wir haben nicht mehr drei ("A", "B" und "C") sondern zwei ("G" (Grundkurs und "E" (Erweiterungskurs) und außerdem viele Integrationskinder mit Lernschwächen. Darauf habe ich auch die Einteilung und meine Schwierigkeitsstufen abgestimmt. Teilweise arbeiten wir auch mit Binnendifferenzierung, das heißt in deinem Kurs sitzen Schülerinnen und Schüler, die mit Aufgaben mit differenzierten Schwierigkeitgraden arbeiten. Meinst du das mit "plakativen Einteilung in (Leistungs-) Klassen für... schwierig und Schwierig von didaktisch fragwürdig im Jahr 2024"? Das ist das Grundprinzip der integrierten Gesamtschule. Was würdest du da anders machen?
Und bei meinem Rechenduell habe ich gute Erfahrungen damit gemacht, die Schülerinnen und Schüler in mehrere Ligen einzuteilen. Ansonsten haben die langsameren Rechner nie eine Chance und sind die Looser.Mit meinem Ansatz funktioniert das gut. Aber auch das muss man nicht machen - kann man aber
Was du im Screenshot siehst ist das Template das ich in der App erstellt habe und darauf bezieht sich meine Frage. Ich habe eine Datenbanktabelle speziell für das Duell erstellt und mit einer OneToOne Bezeihung mit den Profilen der Mitglieder in der Lerngruppe verbunden (die bräuchte man eigentlich nicht unbedingt) und die Einträge in dieser Tabelle werden nur erzeugt wenn die Lehrkraft die Option für das Duell nutzen will. Und das Duell ist auch keine einmalige Sache, die mit einem Durchgang erledigt ist, eine Rangfolge wird erst erstellt, wenn alle mal "dran" waren. Das kann man über das ganze Schuljahr nutzen und daher wollte ich die Daten in dieser Tabelle speichern. Den Code mit der Durchführung bekomme ich hoffentlich hin - eine Vorlage habe ich ja schon. In diesem Post geht es nur darum, wie ich an dem Tag, an dem die Gruppe ein Duell machen will, die Lehrkraft mit einem Klick, die nicht Anwesenden markieren kann. Und dann müsste die Lehrkraft beim ersten Aufruf des Duells, die Schülerinnen und Schüler nunmal möglichst auch in Ligen einteilen können - oder auch nicht wenn er an einer Schule mit abschlussbezogenen Mathematikklassen arbeitet.
Re: Änderungen in Template
Verfasst: Donnerstag 11. Juli 2024, 22:39
von noisefloor
Hallo,
nochmal zur Klarstellung: das ist meine _persönliche_ Meinung dazu. Wenn du es für richtig hältst: ok, du schreibst das Programm und das Quiz.
Und meine Meinung ändert auch nichts dran, dass ich dir nach bestem Wissen und Gewissen bei der Umsetzung helfen. Also: fokussieren wir auf den Code.
Gruß, noisefloor
Re: Änderungen in Template
Verfasst: Donnerstag 11. Juli 2024, 23:05
von Pitwheazle
OK, danke
Also denn:
wenn ich die Zeile:
durch
Code: Alles auswählen
<td><input id="abwesend" name="abwesend" type="Checkbox"></td>
erstze, hätte ich Checkboxen. Diese müssten jetzt aber jeweils mit den IDs der Schülerinnen und Schüler verknüpft werden und außerdem beim nächste Aufruf der Seite angeklickt bleiben. Da fällt mir nichts dazu ein.
Die Seite rufe ich bisher mit
Code: Alles auswählen
path("duell/<int:gruppe_id>/", views.duell, name="duell"),
auf.
Re: Änderungen in Template
Verfasst: Freitag 12. Juli 2024, 05:06
von Sirius3
Du brauchst halt eine neue Tabelle, die gruppe_id, user_id, Liga, Platzierung und alles weitere was jeder Spieler so braucht, speichert.
@noisefloor: Caching ist generell nicht geeignet, weil Caches jederzeit gefahrlos gelöscht werden können, die Daten lassen sich ja wiederherstellen.
Re: Änderungen in Template
Verfasst: Freitag 12. Juli 2024, 08:20
von Pitwheazle
... das habe ich schon gemacht:
Pitwheazle hat geschrieben: Donnerstag 11. Juli 2024, 13:50
Ich sitze jetzt an meinem Rechenduell. Dafür habe ich ein model ... erstellt.
...
Mein model:
.
Code: Alles auswählen
class Duell(models.Model):
profil = models.OneToOneField(Profil, related_name='duellprofil', on_delete=models.CASCADE)
gruppe = models.ForeignKey(Lerngruppe, null= True, blank=True, on_delete = models.CASCADE, related_name='duellgruppe')
liga = models.CharField(max_length=1, default="A")
platz = models.SmallIntegerField(null=True, blank=True)
aufsteiger = models.BooleanField(default=False)
abwesend = models.BooleanField(default=False)
spiele = models.SmallIntegerField(default=0)
punkte = models.DecimalField(max_digits=3, decimal_places=1, default=0)
pps = models.DecimalField(max_digits=4, decimal_places=2, default=0)
Ich packe jetzt meine Teilnehmerr_id hier ind die input id - mal sehen, ob ich damit weiterkomme:
Pitwheazle hat geschrieben: Donnerstag 11. Juli 2024, 23:05
Code: Alles auswählen
<td><input id="abwesend" name="abwesend" type="Checkbox"></td>
Re: Änderungen in Template
Verfasst: Freitag 12. Juli 2024, 08:37
von grubenfox
Pitwheazle hat geschrieben: Donnerstag 11. Juli 2024, 17:46
Hallo @grubenfox Vielen Dank für den Hinweis. Ich bin mir bewusst, dass ich nur kleine Teile von Django, HTML, CSS und Phyton beherrsche und bin dir auch wirklich immer dankbar für deine Tipps - dieser Post ist aber schon arg überheblich.
Darf ich zum einen die gestrige erhöhte Zimmertemperatur und zum anderen die aktuelle Zeitnot beim tippen der Antwort als Teil meiner Bitte um Entschuldigung anführen?
An der Zeitnot lag es dass ich mich nicht wirklich der Frage beschäftigt hatte, sie höchstens halb verstanden hatte und dadurch eine Antwort rausgerotzt hatte, die völlig in die falsche Richtung führte.
Die erhöhte Zimmertemperatur war dann die Ursache dafür das ich dann auf den Knopf "Absenden" geklickt hatte.

Eigentlich hatte ich hier schon gelernt: je spontaner ich eine Frage beantworte, desto saumäßiger ist die Qualität der Antwort und die Antwort gestern hätte ich gar nicht absenden dürfen...
Hätte ich mich ordnetlich mit der Frage beschäftigt, dann hätte ich geantwortet dass das Problem wohl mit Forms am einfachsten und elegantesten zu lösen ist.
Pitwheazle hat geschrieben: Donnerstag 11. Juli 2024, 17:46
Hätte ja sein können, dass es bei Django eine Möglichkeit gibt, mittels Forms eine Auswahl von Instanzen gleichzeitig zu bearbeiten. Ich entnehme deiner Antwort, dass dem nicht so ist
Wobei die Annahme nun auch nicht ganz verkehrt ist: nicht "Form", sondern "FormSet" ist das korrekte Stichwort für Suche in der Doku zum Thema "Bearbeitung von mehreren Instanzen gleichzeitig"....
Mein persönliches Problem mit der Doku von Django ist ja: vor lauter Doku benötige ich immer endlose Zeit bis ich das gefunden habe was ich suchte.... falls ich es nicht gleich komplett übersehe. Die sehr gute und umfangreiche Doku von Django ist für mich irgendwie oft zu umfangreich.
Aber wie ich eben beim durchsuchen der Dokumentation zu Forms feststellte: uns beiden wäre sehr geholfen, wenn es neben den ganzen Texten noch ein paar Abbildungen geben würde wie sich das ganze eigentlich im Browser darstellt. Dann hätte ich schneller erkannt wo wohl die interessanten Textabschnitte beginnen. Ab und an ist ein nettes Bild doch hilfreich...
Re: Änderungen in Template
Verfasst: Freitag 12. Juli 2024, 08:41
von Sirius3
@Pitwheazle: Die Klasse `Duell` habe ich jetzt nicht direkt mit einem `DuellTeilnehmer` assoziiert. Schlechte Namen tragen eben doch nur zur Verwirrung bei.
Die id wird für Formulare ignoriert, da zählt nur der name.
Re: Änderungen in Template
Verfasst: Freitag 12. Juli 2024, 10:30
von Pitwheazle
grubenfox hat geschrieben: Freitag 12. Juli 2024, 08:37
Darf ich zum einen die gestrige erhöhte Zimmertemperatur und zum anderen die aktuelle Zeitnot beim tippen der Antwort als Teil meiner Bitte um Entschuldigung anführen?
Ja, na klar. ich hatte schon befürchtet meine Begriffsstutzigkeit und meine blöden Fragen hätten jetzt dazu geführt, dass du es aufgegeben hast, mir was zu erklären.
grubenfox hat geschrieben: Freitag 12. Juli 2024, 08:37
Mein persönliches Problem mit der Doku von Django ist ja: vor lauter Doku benötige ich immer endlose Zeit bis ich das gefunden habe was ich suchte.... falls ich es nicht gleich komplett übersehe. Die sehr gute und umfangreiche Doku von Django ist für mich irgendwie oft zu umfangreich.
Aber wie ich eben beim durchsuchen der Dokumentation zu Forms feststellte: uns beiden wäre sehr geholfen, wenn es neben den ganzen Texten noch ein paar Abbildungen geben würde wie sich das ganze eigentlich im Browser darstellt. Dann hätte ich schneller erkannt wo wohl die interessanten Textabschnitte beginnen. Ab und an ist ein nettes Bild doch hilfreich...
Das ist schön, dass du das auch so siehst. Wenn ihr mir sagt, dies und das stünde doch in der Dokumentation, dachte ich schon nur ich finde da nix.
grubenfox hat geschrieben: Freitag 12. Juli 2024, 08:37
Hätte ich mich ordnetlich mit der Frage beschäftigt, dann hätte ich geantwortet dass das Problem wohl mit Forms am einfachsten und elegantesten zu lösen ist.
Pitwheazle hat geschrieben: Donnerstag 11. Juli 2024, 17:46
Hätte ja sein können, dass es bei Django eine Möglichkeit gibt, mittels Forms eine Auswahl von Instanzen gleichzeitig zu bearbeiten. Ich entnehme deiner Antwort, dass dem nicht so ist
Wobei die Annahme nun auch nicht ganz verkehrt ist: nicht "Form", sondern "FormSet" ist das korrekte Stichwort für Suche in der Doku zum Thema "Bearbeitung von mehreren Instanzen gleichzeitig"....
"FormSet" kommt mir irgendwie bekannt vor. Da muss ich mal suchen ob ich das nicht schon mal eingestzt habe - oder halt in der Doku

.
Danke erstmal
Nachtrag. Ich habe mich tatsächlich mal mit FormSet beschäftigt und dies mit Google gefunden:
viewtopic.php?t=56508
- da bin ich aber wohl nicht weitergekommen und habe es nicht in meinem Code.
Re: Änderungen in Template
Verfasst: Freitag 12. Juli 2024, 11:12
von Pitwheazle
Sirius3 hat geschrieben: Freitag 12. Juli 2024, 08:41
@Pitwheazle: Die Klasse `Duell` habe ich jetzt nicht direkt mit einem `DuellTeilnehmer` assoziiert. Schlechte Namen tragen eben doch nur zur Verwirrung bei.
Die id wird für Formulare ignoriert, da zählt nur der name.
Ich hatte ja versprochen die Benennungen besser zu machen. Also heißt meine Tabelle jetzt Duellant

Kann ich den den Namen für die Idendifizierung nehmen? (Wofür ist den die id gut?)
Re: Änderungen in Template
Verfasst: Freitag 12. Juli 2024, 11:52
von Pitwheazle
Ich fürchte, auch hier überfordert mich die Beschreibung von FormSet. Ich bin aber trotzdem weiter. Wenn ich
für die Checkbox in der letzten Spalte:
Code: Alles auswählen
<td><input id="abwesend" name={{duellant.id}} type="Checkbox"></td>
als "name" den Duellanten einsetze, bekomme ich mit :
Code: Alles auswählen
<form action="/duell/{{gruppe_id}}"" method="POST">
{% csrf_token %}
...
<td><input id="abwesend" name={{duellant.id}} type="Checkbox"></td>
...
<label >abwesende übernehmen</label>
<input type="submit" name="abwesend" value="speichern"></button>
</form>
und
Code: Alles auswählen
def duell(req, gruppe_id):
if req.method == 'POST':
return HttpResponse(req)
den csf Token und die IDs der Ausgewählten zurück:
Jetzt müsste ich ja nur in einer Schleife für die beiden die Abwesenheit auf "True" setzen. Wie aber bekomme ich die 4 und die 6 jetzt aus dem Request?
Re: Änderungen in Template
Verfasst: Freitag 12. Juli 2024, 14:35
von Pitwheazle
Ich bin zwar noch nicht ganz so alt wie Herr Biden, es wird aber auch bei mir nicht einfacher. Hier
viewtopic.php?t=55759 habe ich so ziemlich das gleiche gefragt - der Unterschied ist also "print(reqPost)".
Mit:
Code: Alles auswählen
<input class="form-check-input" type="checkbox" value={{duellant.id}}, name="ID">
bekomme ich jetzt anscheinend eine Liste mit IDs
Re: Änderungen in Template
Verfasst: Freitag 12. Juli 2024, 15:38
von Pitwheazle
Und jetzt wird auch der Eintrag, ob jemand abwesend ist übernommen:
Code: Alles auswählen
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()
aber ob die Checkbox angelickt ist, bekomme ich nur so hin:
Code: Alles auswählen
{% if duellant.abwesend%}
<input class="form-check-input" type="checkbox" value={{duellant.id}} name="ID" checked>
{%else%}
<input class="form-check-input" type="checkbox" value={{duellant.id}} name="ID" >
{%endif%}
... ob das auch anders geht?
PS. Warum wird die ID als string übergeben?
Re: Änderungen in Template
Verfasst: Freitag 12. Juli 2024, 21:51
von __blackjack__
@Pitwheazle: Als was sollte die ID denn sonst übergeben werden? Es gibt da nur Zeichenketten.
Warum noch mal `list()` bei dem Ergebnis von `getlist()`? Wenn man das unbedingt noch mal in eine andere Datenstruktur kopieren will, würde sich da deutlich eher ein `set()` anbieten. Und man könnte die IDs dann auch in Zahlen umwandeln statt die Vergleichs-IDs in Zeichenketten.
Der ``in``-Operator liefert bereits `True` oder `False`. Anhand dessen noch mal zu entscheiden ob man da nun `True` oder `False` haben möchte ist ein unnötiger Schritt. Also einfach nur:
Beziehungsweise auch noch ohne das `str()` wenn man die IDs vorher in Zahlen umgewandelt hat.
Re: Änderungen in Template
Verfasst: Freitag 12. Juli 2024, 21:54
von Pitwheazle
Danke, - das ändere ich. Ich lerne immer wieder dazu (und vergesse leider genauso viel)
Ich dachte, die ID einer Instanz sei ein Integerwert
Re: Änderungen in Template
Verfasst: Freitag 12. Juli 2024, 22:26
von __blackjack__
@Pitwheazle: Ist die ID ja auch. In der Datenbank. In Python. Aber HTTP ist halt ein Textprotokoll das keine Datentypen kennt. Bei einer Anfrage vom Browser kann nur Text mitgeliefert werden. Beziehungsweise Bytes.