Django {% if user.is_authenticated %}

Django, Flask, Bottle, WSGI, CGI…
Antworten
guhamail
User
Beiträge: 12
Registriert: Samstag 19. Februar 2022, 13:34

Hallo in die Gruppe,

ich bin gerade dabei mich in Python und Django einzuarbeiten. Als Übungsobjekt soll eine kleine Vereinswebseite erstellt werden. Ich bin auf folgendes (für mich derzeit unlösbares) Problem gestoßen:

Für meine Seite habe ich 2 Apps erstellt: Testseite1 und Testseite2
Für beide Seiten gibt es ein base.html Template. In einer Navbar soll der Name des angemeldeten Benutzers angezeigt werden.

Code: Alles auswählen

.
.
.
<div class="badge bg-primary text-wrap" >
            base: {{user}}
            {% if user.is_authenticated %}
              {{user}}
            {% else %}
              <p>nicht angemeldet</p>
            {% endif %}
     </div>
    .
    .
    .    
Zu Testzwecken habe ich {{user}} 2x drin, einmal außerhalb von if und einmal innerhalb von if.

Das Template von Testseite1 sieht so aus...

Code: Alles auswählen

{% extends 'base.html'%}
{% block content %}

<p>Testseitentext</p>


{% endblock %}
... und wird mit folgendem view aufgerufen:

Code: Alles auswählen

from django.shortcuts import render

def html(request):
    context= {'title': "Test", 'user': request.user}
    return render(request=request, template_name='index/testseite.html', context=context)


Das Template von Testseite2..

Code: Alles auswählen

{% extends 'base.html'%}
{% block content %}
<table class="table table-striped">
    <tr>
        <th>Belegnummer</th>
        <th>Datum</th>
        <th>Buchungstext</th>
        <th>Kategorie</th>
        <th>Betrag</th>
        <th>Vorschuss</th>
    </tr>
    {% for row in daten %}
    <tr>
        <td>{{row.0}}</td>
        <td>{{row.1}}</td>
        <td>{{row.2}}</td>
        <td>{{row.3}}</td>
        <td>{{row.4}}</td>
        <td>{{row.5}}</td>
        
    </tr>
    {% endfor %}
</table>
    

{% endblock %}

...wird mit folgendem view aufgerufen:

Code: Alles auswählen

from django.shortcuts import render
import csv 

def html(request):
   with open(r'C:\Users\Test\Nextcloud4\Kassenbuch\2022\Journal.csv') as csvFile:
        csv_objekt = csv.reader(csvFile, delimiter=',')
        i=0
        Abteilung=str(request.user)
        if Abteilung=="12-Tischtennis":
            for row in csv_objekt:
                if i<3:
                    i=i+1
                    continue 
                if i==3:
                    kassenstand=row[32]
                    i=i+1
                    continue
                if i==4:
                    i=i+1
                    continue
                if row[31]!="":
                    daten.append([row[1], row[2], row[3], row[6], row[31], row[32]])
            context={'daten': daten, 'kasse': kassenstand, 'user': Abteilung, 'title': "Testtietel"}
        elif Abteilung=="15-Vorstand":
            for row in csv_objekt:
                if i<3:
                    i=i+1
                    continue 
                if i==3:
                    kassenstand=row[16]
                    i=i+1
                    continue
                if i==4:
                    i=i+1
                    continue
                if row[15]!="":
                    daten.append([row[1], row[2], row[3], row[6], row[15], row[16]])
            context={'daten': daten, 'kasse': kassenstand, 'user': Abteilung, 'title': "Testtietel"} 
        elif Abteilung=="16-Angeln":
            for row in csv_objekt:
                if i<3:
                    i=i+1
                    continue 
                if i==3:
                    kassenstand=row[18]
                    i=i+1
                    continue
                if i==4:
                    i=i+1
                    continue
                if row[17]!="":
                    daten.append([row[1], row[2], row[3], row[6], row[17], row[18]])
            context={'daten': daten, 'kasse': kassenstand, 'user': Abteilung, 'title': "Testtietel"} 
        else:
            context={}

    return render(request=request, template_name='index/index.html', context=context)

Der Code sieht bestimmt wie Anfängercode aus, ist aber egal. Er funktioniert und das reicht mir.
Nun zum eigentlichen Problem:

Der Name des angemeldetet Users wird in der Navbar nicht immer angezeigt. Rufe ich Testseite1 auf, funktioniert es tadellos. Das heißt, beide {{user}} im base.html (sowohl innerhalb des if als auch außerhalb) werden korrekt ausegegeben. Rufe ich dagegen Testseite2 auf, ist das anders. Der erste {{user}} im base.html wird korrekt ausgegeben, wärend der 2. (innerhalb von if) nicht ausgegeben wird. Stattdessen erscheint dort der Text aus dem else. Wie kann das sein? Ich finde keine Lösung.
Benutzeravatar
sparrow
User
Beiträge: 4186
Registriert: Freitag 17. April 2009, 10:28

Grunsätzlich:
Namen werden in python klein_mit_unterstrich geschrieben. Außer die Namen von Klassen (PascalCase) (nicht die Namen von Instanzen!) und Konstanten (KOMPLETT_GROSS).

Deine if-continue-Kaskaden sehe nicht gut aus.

Die string-Representation an den Namen "Abteilung" (sollte eigentlich abteilung sein) zu binden, halte ich schon für falsch. Man verwendet die String-Representation eigentlich gar nicht. Wenn du den Namen des users haben möchtest, dann verwende das entsprechende Attribut von "user".
Aber das dann auch noch als "user" dem Template zu übergeben, ist definitiv falsch.
guhamail
User
Beiträge: 12
Registriert: Samstag 19. Februar 2022, 13:34

Grunsätzlich:
Namen werden in python klein_mit_unterstrich geschrieben. Außer die Namen von Klassen (PascalCase) (nicht die Namen von Instanzen!) und Konstanten (KOMPLETT_GROSS).
Wenn ich ehrlich bin, hat man es mir auch irgendwann mal so beigebracht. Aber im Eifer des Gefechts, wenn man Ideen im Kopf hat die man schnell umsetzen möchte, denke ich an soetwas nicht. Ich gelobe Besserung.
Aber das dann auch noch als "user" dem Template zu übergeben, ist definitiv falsch.
Vielen Dank für den Hinweis. Wenn man so darauf hingewiesen wird, merkt man erst das es natürlich eine große Dummheit ist, das als "user" zu übergeben. Geändert - jetzt funktionierts.
...dann verwende das entsprechende Attribut von "user".
Klar, geht so auch viel einfacher. Manchmal mache ich mir das Leben halt selbst ein wenig schwerer :oops:

Vielen Dank für deine Unterstützung.
Benutzeravatar
sparrow
User
Beiträge: 4186
Registriert: Freitag 17. April 2009, 10:28

Also das, was du da mit deinem hochzählen von "i" machst, finde ich extrem seltsam.
Warum machst du das?

Kannst du mir den Unterschied erklären zwischen deinem Code:

Code: Alles auswählen

                if i<3:
                    i=i+1
                    continue 
                if i==3:
                    kassenstand=row[32]
                    i=i+1
                    continue
                if i==4:
                    i=i+1
                    continue
                if row[31]!="":
                    daten.append([row[1], row[2], row[3], row[6], row[31], row[32]])
Und dem was ich glaube, was er tut:

Code: Alles auswählen

                kassenstand=row[32]
                daten.append([row[1], row[2], row[3], row[6], row[31], row[32]])
guhamail
User
Beiträge: 12
Registriert: Samstag 19. Februar 2022, 13:34

Folgendes möchte ich erreichen:

DIe csv hat ca. 1.000 Zeilen mit jeweils ca. 50 Daten pro Zeile.
DIe ersten 3 Zeilen der csv sollen übersprungen werden, da ich die Daten darin nicht benötige.
In der 4. Zeile benötige ich nur den 32. Datesatz und ab der 6. Zeile benötige ich dann einige mehr.

Es gibt bestimmt noch eine elegantere Lösung für meinen usecase, aber für mich war das erstmal der Weg, der funktioniert.
Benutzeravatar
sparrow
User
Beiträge: 4186
Registriert: Freitag 17. April 2009, 10:28

Das klingt nach einer kaputten Datenquelle.

Code: Alles auswählen

            for row_number, row in enumerate(csv_objekt):
                if row_number == 3:
                    kassenstand=row[32]
                elif row_number > 4:
                    daten.append([row[1], row[2], row[3], row[6], row[31], row[32]])
            context={'daten': daten, 'kasse': kassenstand, 'user': Abteilung, 'title': "Testtietel"}
Sirius3
User
Beiträge: 17738
Registriert: Sonntag 21. Oktober 2012, 17:20

Eingerückt wird immer mit 4 Leerzeichen pro Ebene, nicht mal 3 und mal 5.
Du hast drei mal fast identischen Code, der sollte nur einmal existieren. Statt dessen verwendet man eine passende Parametrisierung. Wenn man sich auschließende if-Anweisungen hat, dann benutzt man elif. `continue` sollte man so weit es geht vermeiden:

Code: Alles auswählen

import csv 

IMPORTANT_COLUMNS_FOR_ABTEILUNG = {
    "12-Tischtennis": (31, 32),
    "15-Vorstand": (15, 16),
    "16-Angeln": (17,18),
}

JOURNAL_FILENAME = r'C:\Users\Test\Nextcloud4\Kassenbuch\2022\Journal.csv'

def read_csv(abteilung):
    if abteilung not in IMPORTANT_COLUMNS_FOR_ABTEILUNG:
        return {}
    column_nr1, column_nr2 = IMPORTANT_COLUMNS_FOR_ABTEILUNG[abteilung]
    with open(JOURNAL_FILENAME) as csv_file:
        rows = csv.reader(csv_file, delimiter=',')
        daten = []
        for row_index, row in enumerate(rows):
            if row_index == 3:
                kassenstand = row[column_nr2]
            elif row_index > 4 and row[column_nr1] != "":
                daten.append([row[1], row[2], row[3], row[6], row[column_nr1], row[column_nr2]])
    return {
        'daten': daten,
        'kasse': kassenstand,
        'user': abteilung,
        'title': "Testtietel",
    }
Statt innerhalb einer for-Schleife verschieden Dinge zu tun, die am Zeilenindex hängen, schreibt man die Sonderbehandlung einfach vor der for-Schleife:

Code: Alles auswählen

def read_csv(abteilung):
    if abteilung not in IMPORTANT_COLUMNS_FOR_ABTEILUNG:
        return {}
    column_nr1, column_nr2 = IMPORTANT_COLUMNS_FOR_ABTEILUNG[abteilung]
    with open(JOURNAL_FILENAME) as csv_file:
        rows = csv.reader(csv_file, delimiter=',')
        _ = next(rows), next(rows), next(rows)
        kassenstand = next(rows)[column_nr2]
        _ = next(rows)
        daten = [
            [row[1], row[2], row[3], row[6], row[column_nr1], row[column_nr2]]
            for row in rows if row[column_nr1] != ""
        ]
    return {
        'daten': daten,
        'kasse': kassenstand,
        'user': abteilung,
        'title': "Testtietel",
    }
guhamail
User
Beiträge: 12
Registriert: Samstag 19. Februar 2022, 13:34

sparrow hat geschrieben: Samstag 19. Februar 2022, 19:31 Das klingt nach einer kaputten Datenquelle.

Code: Alles auswählen

for row_number, row in enumerate(csv_objekt):
    if row_number == 3:
        kassenstand=row[32]
    elif row_number > 4:
        daten.append([row[1], row[2], row[3], row[6], row[31], row[32]])
        context={'daten': daten, 'kasse': kassenstand, 'user': Abteilung, 'title': "Testtietel"}
Hallo,

das schaut gut aus. Ich habe den Code dann so übernommen. Es ärgert mich ein wenig, nicht selbst darauf gekommen zu sein. Das mit enumerate() hätte ich wissen müssen.
Eingerückt wird immer mit 4 Leerzeichen pro Ebene, nicht mal 3 und mal 5.
In meiner IDE ist alles perfekt eingerückt. Beim kopieren des Codes hier ins Forum ist mir da wohl ein wenig verrutscht. Werd ich nächstes mal besser drauf achten.

Code: Alles auswählen

with open(JOURNAL_FILENAME) as csv_file:
    rows = csv.reader(csv_file, delimiter=',')
    _ = next(rows), next(rows), next(rows)
    kassenstand = next(rows)[column_nr2]
    _ = next(rows)
    daten = [
        [row[1], row[2], row[3], row[6], row[column_nr1], row[column_nr2]]
        for row in rows if row[column_nr1] != ""
    ]
Das muss ich mir in einer ruhigen Minute mal genauer ansehen.

Ich danke euch beiden recht herzlich für eure Unterstützung.
Antworten