Ist Django für mein Projekt geeignet?

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

Solange ich noch auf eine göttliche Eingebung für obiges Problem warte, habe ich noch was neues:

Es kommen immer schön 10 Aufgaben am Stück und sie sind (glaube ich) auch ordentlich formatiert. Jetzt hätte ich gerne, dass ich (der Nutzer) nicht immer zunächst in das Aufgabenfeld klicken muss. Da kann man doch sicher automatisch einen Focus setzen. Die Beispiele, die ich dazu gegoogelt habe, sehen alle anders aus. Ich vermute, das muss hier in den Code:

Code: Alles auswählen

<form action="{% url 'main' kategorie.slug %}" method="post">
    {% csrf_token %}
    <fieldset>
        {{ form.eingabe.label_tag }}
        {{ form.eingabe }}
        <input class="button-primary" type="submit" value="Prüfen">
    </fieldset>
</form>
Benutzeravatar
Whitie
User
Beiträge: 216
Registriert: Sonntag 4. Juni 2006, 12:39
Wohnort: Schulzendorf

Es gibt da das "autofocus" Attribut für Formularfelder. Ob das korrekt funktioniert musst du mal testen. Einfügen musst du es nicht im HTML-Code (Template), sondern in deinem Formular:

Code: Alles auswählen

class EingabeForm(forms.Form):
    eingabe = forms.CharField(label='Eingabe', widget=forms.TextInput(attrs={'autofocus': True}))
Falls das kein TextInput ist, musst du den Code entsprechend anpassen. Wenn du das ganze nicht über das Formular lösen möchtest, kann man das auch mit Javascript machen.

Viele Grüße
Whitie
Pitwheazle
User
Beiträge: 869
Registriert: Sonntag 19. September 2021, 09:40

Prima, danke!
Natürlich ist es aber kein TextInput, ich habe gegoogelt und es geändert:

Code: Alles auswählen

class AufgabeFormZahl(forms.Form):
    eingabe = forms.DecimalField(label='Ergebnis', max_digits=15,
                                decimal_places=5, widget=forms.NumberInput(attrs={'autofocus': True}))
... das scheint zu funktionieren.
Pitwheazle
User
Beiträge: 869
Registriert: Sonntag 19. September 2021, 09:40

Hallo Whitie, ich habe jetzt eine grundlegende Frage:
Die Grundlage meiner Arbeit ist ja ein Entwurf von dir. In den Funktionen "ergaenzen", "addieren" usw werden Zahlen erzeugt ("low", "high") und im Model "question" sind Fragen gespeichert. (z.B. "Ergänze {low:.2f} zu {high:.2f}"). Ich könnte aber doch den gesamten Aufgabentext in den Funktionen erstellen. So muss ich die Zahlen im Codeeditor erstellen und die Fragen im Adminbereich. Wo liegt der Vorteil? Für mich wäre es einfacher und übersichtlicher dies nicht zu trennen. Der einzige Vorteil, den ich erkennen kann, wäre, das man den Rechentrainer einfacher in eine andere Sprache übersetzen kann - oder übersehe ich da etwas?
Benutzeravatar
Whitie
User
Beiträge: 216
Registriert: Sonntag 4. Juni 2006, 12:39
Wohnort: Schulzendorf

Der Vorteil wäre, dass ganz leicht (über den Adminbereich) neue/andere Fragetexte ergänzt werden können. Natürlich kannst du das auch komplett in deinen Funktionen machen, aber alle Fragen wären dann im Quelltext. Eine Änderung/Ergänzung müsste dann immer im Quelltext passieren und die Aktivierung ginge nur durch Neustart der App.
Die Fragen sind für mich typische DB Daten.
Übersetzungen hatte ich nicht im Sinn, die gehen auch im Quelltext (Stichwort: gettext).

Viele Grüße
Whitie
Pitwheazle
User
Beiträge: 869
Registriert: Sonntag 19. September 2021, 09:40

Danke, das ist sehr erhellend. Ich orientiere mich aber an meinem existierenden Rechentrainer und da waren die Fragetexte alleine nicht weiter wichtig. Wenn ich Änderungen vorgenommen habe, betrafen diese ganze Aufgabentypen und die hätten hauptsächlich den Code betroffen. Richtig beurteilen kann ich das aber wohl erst, wenn ich die App nicht nur auf meinem Rechner laufen lasse. Ich bin mir aber sicher, dass ich die Fragetexte jetzt getrost in den Code integrieren kann, so kann ich mich am Aufbau meines existierenden Projektes entlanghangeln.
Pitwheazle
User
Beiträge: 869
Registriert: Sonntag 19. September 2021, 09:40

Mit meinem obigen Problem mit der Verarbeitung der angewählten Optionen bin ich auch etwas weitergekommen. Nur das letzte Stück fehlt noch. Ich will also auswerten was jeweils unter "bis_stufe" bei der ausgewählten Option steht (Eigentlich brauche ich nur die größte Zahl von allen - wenn es denn mehrere sind).
Der Code:

Code: Alles auswählen

 if zaehler.optionen_text != "":     
                        auswahl = Auswahl.objects.filter(kategorie = kategorie_id)
                        optionen = zaehler.optionen_text.split(";")
                        for o in optionen:
                            wahl = auswahl.filter(text = o)
                            print(wahl)    
... gibt mir

Code: Alles auswählen

<QuerySet [<Auswahl: mit Kommazahlen>]>
<QuerySet [<Auswahl: noch eine Auswahl>]>
zurück. Aber mit

Code: Alles auswählen

print(wahl.bis_stufe)
erhalte ich die Meldung

Code: Alles auswählen

'QuerySet' object has no attribute 'bis_stufe'
Hat es aber doch - oder?

Code: Alles auswählen

class Auswahl(models.Model):
    kategorie = models.ForeignKey(Kategorie, null=True, on_delete=models.CASCADE)
    text = models.CharField(max_length=80, verbose_name="Text")
    bis_stufe = models.IntegerField(default=0, verbose_name="bis Stufe:")


    def __str__(self):
        return self.text 
Benutzeravatar
sparrow
User
Beiträge: 4164
Registriert: Freitag 17. April 2009, 10:28

Die Methode .filter() auf einem Queryset schränkt das Ergebnis der Abfrage ein. Es kann aber immer noch mehr als ein Element das Ergebnis der Abfrage sein.
Wie die Fehlermeldung sagt: 'QuerySet" hat kein Attribut namens "bis_stufe". "Auswahl" hat ein Attribut namens "bis_stufe".
Du hast aber ein QuerySet, in dem sich (in deinem Fall) ein Element vom Typ "Auswahl" befindet.
Entweder musst du statt .filter() .get() verwenden (und bekommst dann eine Ausnahme, falls keines oder mehrere Elemente existieren, die deiner Auswahl ensprechen) oder du musst die Elemente, die das Ergebnis der Abfrage sind, als einzelne Elemente behandeln - zum Beispiel indem du über die einzelnen Elemente iterierst.
Pitwheazle
User
Beiträge: 869
Registriert: Sonntag 19. September 2021, 09:40

Prima, jetzt funktioniert es (ist aber sicher etwas umständlich)

Code: Alles auswählen

                if zaehler.aufgnr>10:                                       #10 Aufgaben
                    if zaehler.optionen_text != "" and zaehler.optionen_text != "keine":     #wenn Otionen gewählt wurden wird hier die Stufe entsprechend höhergesetzt
                        auswahl = Auswahl.objects.filter(kategorie = kategorie_id)
                        optionen = zaehler.optionen_text.split(";")
                        max = 3
                        for o in optionen:
                            wahl = get_object_or_404(Auswahl, kategorie = kategorie_id, text=o)
                            if wahl.bis_stufe  > max:
                                max = wahl.bis_stufe
                            if max > user.stufe:
                                user.stufe = max
                                if user.e_kurs:
                                    user.stufe += 1 
                                user.save()  
Ansonsten habe ich das mit dem Queryset wahrscheinlich noch nicht wirklich kapiert. In meinem jugendlichen Leichtsinn :) war ich jetzt davon ausgegangen, dass ich, wenn ich sicherstelle, dass da nur ein Element drin ist, auch auf dieses zugreifen kann.
__deets__
User
Beiträge: 14493
Registriert: Mittwoch 14. Oktober 2015, 14:29

Na das waere ja furchtbar, wenn das so ist. Denn wenn du Code hast, bei dem es mal 0, mal 1, mal n Eintraege sein koennten, dann muesste da ja muehselig auf None oder nicht None und dann aber vielleicht eine Sequenz geprueft werden, aber wehe das eine Objekt waere *auch* eine Sequenz (geht in Python problemlos). So ein API waere wirklich ganz grauenvoll.
Benutzeravatar
__blackjack__
User
Beiträge: 13003
Registriert: Samstag 2. Juni 2018, 10:21
Wohnort: 127.0.0.1
Kontaktdaten:

@Pitwheazle: Wollte gerade schreiben das eine ``if`` kann man sich mit der `max()`-Funktion sparen als mir auffiel, dass die `max()`-Funktion nicht mehr verfügbar ist weil da eine 3 dran gebunden wurde an den Namen.

Wenn man den gleichen Wert gegen mehrere andere Werte testen will, kann man oft ``not`` oder ``not in`` und eine Liste mit den Werten verwenden.

`auswahl` wird definiert aber nicht verwendet, jedenfalls nicht in dem Code der direkt danach folgt. Das würde ich näher an die Verwendung verschieben. Falls am Ende nicht `wahl` und `auswahl` parallel benötigt werden, würde ich da keine zwei Namen für verwenden sondern beides `auswahl` nennen. Wobei selbst wenn beides gleichzeitig existieren muss, sind die Namen `wahl` und `auswahl` nicht gut, denn da weiss der Leser nicht wirklich was die jeweils bedeuten, also warum zwei und was die unterscheidet. Oder ist `auswahl` hier nur ein Rest vom vorherigen Code der nicht mehr verwendet wird?

`o` ist kein guter Name.

Letztlich ist die `get()`-Methode aber auch sinnvoller als hier `get_object_or_404()` zu verwenden. Wobei das ja für jede Option eine Anfrage bedeutet, da wäre es IMHO sinnvoller nur eine Anfrage zu machen, die gleich alle passenden `Auswahl`-Objekte liefert.

Ungetestet:

Code: Alles auswählen

                if zaehler.aufgnr > 10 and zaehler.optionen_text not in [
                    "",
                    "keine",
                ]:
                    #
                    # Falls Optionen gewählt wurden, wird hier die Stufe
                    # entsprechend höhergesetzt.
                    #
                    max_stufe = 3
                    for auswahl in Auswahl.objects.filter(
                        kategorie=kategorie_id,
                        text__in=zaehler.optionen_text.split(";"),
                    ).all():
                        auswahl.bis_stufe = max(auswahl.bis_stufe, max_stufe)
                        if max_stufe > user.stufe:
                            user.stufe = max_stufe
                            if user.e_kurs:
                                user.stufe += 1
                            user.save()
“Most people find the concept of programming obvious, but the doing impossible.” — Alan J. Perlis
Pitwheazle
User
Beiträge: 869
Registriert: Sonntag 19. September 2021, 09:40

Ach Leute, ihr seid ja so lieb zu mir. Wenn ihr mir weiter so geduldig helft, werde ich das mit Django und Python vielleicht doch noch ein bisschen lernen! Ich schreibe halt immer noch so, wie ich es aus Basic kenne, lerne, durch eure Beispiele aber ständig dazu.
__blackjack__ hat geschrieben: Donnerstag 19. Mai 2022, 17:01 @Pitwheazle: Wollte gerade schreiben das eine ``if`` kann man sich mit der `max()`-Funktion sparen als mir auffiel, dass die `max()`-Funktion nicht mehr verfügbar ist weil da eine 3 dran gebunden wurde an den Namen.
... nun ja, das "max = 3" habe ich nur geschrieben, um ein Variable "max" zu initieren (heißt das so?) weil ich mit "max()" noch nicht umgehen kann. Wenn ich wüsste, wie man "max()" in diesem Zusammenhang nutzen kann, wäre es natürlich besser.
__deets__ hat geschrieben: Donnerstag 19. Mai 2022, 16:21 Na das waere ja furchtbar, wenn das so ist. Denn wenn du Code hast, bei dem es mal 0, mal 1, mal n Eintraege sein koennten, dann muesste da ja muehselig auf None oder nicht None ...
... ich hatte ja geschrieben, dass ich genau nur ein Element erwarte:
Pitwheazle hat geschrieben: Donnerstag 19. Mai 2022, 16:18 In meinem jugendlichen Leichtsinn :) war ich jetzt davon ausgegangen, dass ich, wenn ich sicherstelle, dass da nur ein Element drin ist, auch auf dieses zugreifen kann.
Wie mache ich das denn jetzt überhaupt? Das (der?) Query gibt mir eine Suche zurück, mit den Objekten, die meine Bedingung erfüllen. Wie aber arbeite ich damit? Mit einer Schleife?
Nachdem das jetzt mit dem Auslesen der gewählten Optionen (umständlich) klappt, hatte ich den Ehrgeiz es auch anders zu probieren. Diese lese ich mit:

Code: Alles auswählen

        if form.is_valid():
            zaehler.optionen.set(form.cleaned_data['optionen'])
            optionen_text = ';'.join(map(str, form.cleaned_data['optionen']))
... die obere Zeile ist die Empfehlung von Whitie (mit der ich nicht umgehen kann), die untere nutze ich zurzeit.

Code: Alles auswählen

                if zaehler.aufgnr > 10 and zaehler.optionen_text not in ["", "keine",]:
                    print(zaehler.optionen_text)
                    print(zaehler.optionen)
... gibt mir

Code: Alles auswählen

mit Kommazahlen;noch eine Auswahl
core.Auswahl.None
... zurück. Was meint ihr: Soll ich es mit meiner Version gut sein lassen, oder geht es mit Whities Vorschlag besser?
Die Felder im model "Zaehler":

Code: Alles auswählen

    optionen = models.ManyToManyField(Auswahl)
    optionen_text=models.CharField(max_length=100, blank=True, verbose_name="Optionen")
Benutzeravatar
__blackjack__
User
Beiträge: 13003
Registriert: Samstag 2. Juni 2018, 10:21
Wohnort: 127.0.0.1
Kontaktdaten:

@Pitwheazle: Auch wenn man mit eingebauten Funktionen nicht umgehen kann, oder sie schlicht nicht braucht, sollte man deren Namen nicht für etwas anderes verwenden, weil es den Leser verwirrt. Wenn ich `max` als alleinstehenden Namen lese, dann ist das in meinem Kopf die `max()`-Funktion und ich muss jedes mal dagegen ”ankämpfen” wenn das irgendwo an einen anderen Namen gebunden wird.

Der Umgang mit `max()` ist aber auch einfach. Mit mehreren Argumenten aufgerufen liefert das den grössten Wert. Daraus folgt:

Code: Alles auswählen

if a > b:
    b = a

# =>

b = max(a, b)
Das *Du* nur ein Element erwartest weiss doch aber Python nicht. Und das Problem das __deets__ beschrieben hat bleibt ja bestehen: Was ist bei Abfragen wo Du nicht weisst wie viele Elemente als Ergebnis geliefert werden? Dann würde sich das Ergebnis komplett anders verhalten je nach dem ob da nur ein Element oder mehrere geliefert werden und jeder Code müsste erst einmal prüfen welche Fall vorliegt, und müsste die unterschiedlich behandeln, selbst wenn sie am Ende gleich behandelt werden sollen. Was ja meistens der Fall ist.

Ein `QuerySet` beschriebt erst einmal nur die Abfrage. Das oder die Ergebnisse, also auch das auslösen der tatsächlichen Anfrage an die Datenbank, wird erst ausgelöst wenn man auf Ergebnisse zugreift. Zum Beispiel mit `all()` alle Ergebnisse abfragt, oder mit `get()` genau *ein* Element abfragt. Sowohl kein Element als auch mehrere Elemente führen bei `get()` zu einer Ausnahme.

Also ich würde in der Regel nicht mehrere Werte als Text in einem Feld speichern die dann eigentlich Fremdschlüssel in eine andere Tabelle sind.
“Most people find the concept of programming obvious, but the doing impossible.” — Alan J. Perlis
Pitwheazle
User
Beiträge: 869
Registriert: Sonntag 19. September 2021, 09:40

Auch das ist mal wieder erhellend. Diese Query Abfrage ist also noch kein Zugriff auf die Datenbank, die bekomme ich dann z.B. mit all(). Das muss ich ausprobieren.
Das dauert aber möglicherweise. Ich bin jetzt auf dem Sprung von Naxos nach Amorgos und muss dann erst noch mal auf Tourist machen.
(Daher geht das auch nur so langsam voran).
So long
Benutzeravatar
sparrow
User
Beiträge: 4164
Registriert: Freitag 17. April 2009, 10:28

Du baust eine Query auf. Also eine SQL Abfrage. Erst wenn das Ergebnis tatsächlich angefragt wird, wird diese Query evaluiert und ergibt ein Queryset.

Auch .all() evaluiert das Queryset noch nicht. Erst wenn das auf das Ergebnis zugreifst oder eine Methode aufrufst, die das Ergebnis in eine Datenstruktur überführt.

Hier wird das erklärt.
Pitwheazle
User
Beiträge: 869
Registriert: Sonntag 19. September 2021, 09:40

Toll, danke - wenn man weiß wo man suchen muss! "when querysets are evaluated" Ich finde irgendwie nie die entscheidenden Stellen in der Dokumentation! Will nicht jemand von euch mal ein Buch zu Django schreiben? Eines, in dem das alles drinsteht und das ich von vorne bis hinten lesen kann? So eines habe ich zu den Makros in StarOffice gelesen und das hat ungemein geholfen. So habe ich jetzt mehrere Tutorien durchgearbeitet. Da wird dann immer alles am beispiel eines Projektes besprochen, da kann ich nachsehen (wobei ich es hochgradig lästig finde in einem Video etwas suchen zu müssen, anstelle in einem Buch zu blättern) aber das passt dan halt immer nur zum Teil zu meinen Problemen. Es gibt zwei Bücher in englisch, die werde ich mir nach meiner Heimkunft dann mal bestellen. Sie haben zwar keine so guten Rezensionen, es gibt aber anscheinend nichts umfassendes.

Wollt ihr mir solange beim nächsten Problem helfen?
Bild
Gelb ist meine Aufgabe, wenn ich sie falsch beantworte, bekomme ich in grün einen entsprechenden Hinweis und wenn ich auf "Abbrechen" klicke komme ich zurück zu meiner Kategorieswahl.a

Jetzt bastele ich an "Lösung anzeigen". Wenn ich darauf klicke, soll die Lösung der letzten Aufgabe in grün auftauchen und in gelb eine neue Aufgabe.

Die Lösung steht in der Datebank "Protokoll". Dort erhält jede Aufgabe einen neuen Eintrag (das ist noch von whitie). Das passiert im view "main". Ich versuche hier ml die entsprechenden Codezeilen einzufügen und die m.E. irrelevanten wegzulassen:

Code: Alles auswählen

def main(req, slug):                                                        #hier läuft alles zusammen
    kategorie = get_object_or_404(Kategorie, slug = slug)
    kategorie_id = kategorie.id
    user = get_fake_user()    
    zaehler = get_object_or_404(Zaehler, kategorie = kategorie, user = user)
    if req.method == 'POST':                                                
        protokoll = Protokoll.objects.get(pk = req.session.get('eingabe_id'))
        protokoll.tries += 1
        zaehler = Zaehler.objects.get(pk = req.session.get('zaehler_id'))
        frage = get_object_or_404(Frage, pk = protokoll.frage_id)
        form = AufgabeFormZahl(req.POST)
        right = protokoll.value
        if form.is_valid():                                                 #Aufgabe beantwortet
            eingabe = form.cleaned_data['eingabe']
...
            protokoll.save()
            if kontrolle(eingabe, right):                                   #Anwort richtig
                protokoll.wertung = "richtig"
                protokoll.save()
                zaehler.richtig += 1
...
                msg = f'richtig: {zaehler.richtig}, falsch: {zaehler.falsch}, Fehlerquote: {quote}%'
                messages.info(req, f'Richtig! Versuche: {protokoll.tries}, {msg}')
                return redirect('main', slug)
            else:                                                           #Antwort falsch
                protokoll.wertung = "f"
                protokoll.save()
                zaehler.falsch += 1
...
                zaehler.save()
....
                msg = f'falsch: {zaehler.richtig}, falsch: {zaehler.falsch}, Fehlerquote: {quote}%'
                messages.info(req, f'Leider falsch! Versuche: {protokoll.tries}, {msg}')        
                text = protokoll.text
...
    else:                                                                   #Aufgabenstellung
        frage = Frage.objects.filter(kategorie = kategorie).order_by('?').first()
        frage_id = frage.id
        form = AufgabeFormZahl()
        user = get_fake_user()
        if zaehler.optionen_text == "":                                     #Aufgaben Einstellung
            return redirect('optionen', slug)
        typ, zahl1, zahl2, result = aufgaben(kategorie.id, typ_anf = zaehler.typ_anf, typ_end = zaehler.typ_end, optionen = "") 
        text = frage.text.format(zahl1 = zahl1, zahl2 = zahl2)
        protokoll = Protokoll.objects.create(
            user = user, kategorie = kategorie, text = text, value = result, loesung = str(result)         
        )                                                                   #Protokoll wird erstellt
        req.session['eingabe_id'] = protokoll.id    
        req.session['zaehler_id'] = zaehler.id   
...
        protokoll.typ = typ
        protokoll.frage_id = frage_id
        protokoll.aufgnr = zaehler.aufgnr
...
        protokoll.save()  
    context = dict(kategorie = kategorie, aufgnr = zaehler.aufgnr, text = text, aufgabe = main, form = form, zaehler_id = zaehler.id,)
    return render(req, 'core/aufgabe.html', context)
das sind die Links in meiner Aufgaben.html:

Code: Alles auswählen

    <nav>
        <a href="{% url 'abbrechen' zaehler_id %}">Abbrechen</a>
...
        <a href="{% url 'loesung' eingabe_id %}">Lösung anzeigen</a>
    </nav>
... der Link zu "abbrechen" funktioniert (ich denke, wegen "req.session['zaehler_id'] = zaehler.id)
Also habe ich versuch auf meine Daten in "Protokoll" mit "url 'loesung' eingabe_id" zuzugreifen (wegen: "req.session['eingabe_id'] = protokoll.id"), das klappt nicht:

Code: Alles auswählen

Reverse for 'loesung' with arguments '('',)' not found.
... oder bin ich da wieder auf einem falschen Weg?
Pitwheazle
User
Beiträge: 869
Registriert: Sonntag 19. September 2021, 09:40

Nachtrag:
Ich habe noch ein bisschennrumprobiert und denke, es wäre so besser:
Bild
... das Problem bleibt aber das selbe, wie übergebe ich die Info. Ich habe schon mal das angefangen:

Code: Alles auswählen

<ul>
<h2>{{ kategorie.name }}:</h2>
{% if messages %}
<p>
    Letzte Antwort:
        {% for message in messages %}
        <li>{{ message }}</li>
        {% endfor %}
</p>
{% endif %}
<h3>Aufg. Nr. {{aufgnr}}/10 </h3> 
<h3>{{text}} {{aufgabe}}</h3>
<form action="{% url 'main' kategorie.slug %}" method="post">
    {% csrf_token %}
    <fieldset>
        {{ form.eingabe.label_tag }}
        {{ form.eingabe }}
        <input class="button-primary" type="submit" value="Prüfen">
    </fieldset>
</form>
<form action="{% url ????? %}" method="post">
    {% csrf_token %}
    <fieldset>
        <input class="button-primary" type="submit" value="Lösung anzeigen">
    </fieldset>
</form>
</ul>
... und wie bekomme ich es hin, dass "Lösung anzeigen" und "Hilfe anzeigen" nebeneinander stehen?
Benutzeravatar
Whitie
User
Beiträge: 216
Registriert: Sonntag 4. Juni 2006, 12:39
Wohnort: Schulzendorf

Code: Alles auswählen

Reverse for 'loesung' with arguments '('',)' not found.
Du übergibst eingabe_id nicht in das Template. Daher nimmt Django einen leeren String an. Diese Route gibt es dann nicht.
zaehler_id funktioniert auch nicht magisch durch die Session, sondern du übergibst es im Context. Dort musst du auch eingabe_id einbauen.

Wegen dem Button musst du mal schauen, was es da alles für CSS Klassen gibt für die Positionierung. Dann muss der zweite Button in das selbe "fieldset" wie der submit-Button.

Viele Grüße
Whitie
Pitwheazle
User
Beiträge: 869
Registriert: Sonntag 19. September 2021, 09:40

Na, schon besser:
Bild
... aber so ganz ist es dann doch noch nicht. Die Lösung soll natürlich nur angezeigt werden, wenn "Lösung anzeigen" angeklickt wird. Und dann soll auch nicht die Lösung der aktuellen Aufgabe, sondern die der letzten angezeigt werden. Das habe ich schon mal geändert:

Code: Alles auswählen

<form action="{% url 'loesung' zaehler_id %}" method="get">
    <fieldset>
        <input class="button-primary" type="submit", name="loesung", value="Lösung anzeigen">
        <input class="button-primary" type="submit", name="hilfe", value="Hilfe anzeigen">
    </fieldset>
Ich habe den Buttons Namen gegeben, aber wie und wo kann ich auswerten, welcher Button geklickt wurde? Und die Funktion besteht schon mal aus:

Code: Alles auswählen

def loesung(req, zaehler_id):
    zaehler = get_object_or_404(Zaehler, pk = zaehler_id)
    return redirect('main', zaehler.kategorie)
... es reicht mir ja nicht, die Lösung zur HTML Seite weiterzugeben, ich muss das ja auch in "Zaehler" zählen und, wie gesagt, die Lösung der letzten Aufgabe übergeben. Dazu müsste ich halt jetzt nicht nur die zaehler_id übergeben
zaehler_id funktioniert auch nicht magisch durch die Session, sondern du übergibst es im Context.
ich übergebe sie hier doch nicht im Context, sondern mit der URL

Code: Alles auswählen

path('loesung/<int:zaehler_id>', views.loesung, name='loesung'),
- oder nicht?
Kann ich da nicht auch irgendwie die protokoll_id mit übergeben - oder mit dem Button gleich eine Funktion aufrufen anstelle von dem URL Dingens?
Benutzeravatar
Whitie
User
Beiträge: 216
Registriert: Sonntag 4. Juni 2006, 12:39
Wohnort: Schulzendorf

So ganz klar ist mir nicht, was jetzt wann angezeigt werden soll.
Bis auf den Prüfen Button würde ich alles andere mit Javascript machen.
Antworten