Probleme mit OneToOne Relation

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

Oh Mann, vielleicht wusste ich es ja mal, jetzt bekomme ich es jedenfalls nicht mehr hin.
Also:
ich habe eine OneTo One Relation von meinem User zu seinem Profil:

Code: Alles auswählen

class Profil(models.Model):
    user = models.OneToOneField(User, related_name='profil', on_delete=models.CASCADE )
    nachname = models.CharField(max_length=30)
    vorname = models.CharField(max_length=30)
...    
    gruppe = models.ForeignKey(Lerngruppe, null= True, blank=True, on_delete = models.SET_NULL, related_name='gruppe')
Wenn ein User für eine Gruppe angemeldet ist, benötige ich das Datum, an dem die Gruppe angelegt wurde, wenn der User keiner Gruppe zugeordnet ist, benötige ich das Datum, wann sein Account angelegt wurde. Der erste Teil geht, den zweiten Teil bekomme ich nicht hin. Wie greife ich vom Profil auf das Datum des Accounts zu?

Code: Alles auswählen

    user_gruppe = user.gruppe
    if user_gruppe:
        startdatum = user.gruppe.ab
    else:
        startdatum = user.date_joined
geht natürlich nicht - aber wie ist es richtig?
Benutzeravatar
sparrow
User
Beiträge: 4195
Registriert: Freitag 17. April 2009, 10:28

Und es geht nicht, weil?
Pitwheazle
User
Beiträge: 873
Registriert: Sonntag 19. September 2021, 09:40

Code: Alles auswählen

 	
'Profil' object has no attribute 'date_joined'
Benutzeravatar
sparrow
User
Beiträge: 4195
Registriert: Freitag 17. April 2009, 10:28

Dann steht date_joined offensichtlich nicht in "Profil". In welchem Model ist es enthalten?
Pitwheazle
User
Beiträge: 873
Registriert: Sonntag 19. September 2021, 09:40

Nein, der Eintrag wird aber automatisch angelegt, wenn ein Account angelegt wird. Wo dieses model gescpeichert wird und wie man darauf zugreift hat sich mir noch nicht erschlossen. Ich habe ja geschrieben, dass es eine OneToOne Relation vom Profil zum Useraccount gibt. An anderer Stelle ist es mir aber gelungen im Profil darauf zuzugreifen (und das funktioniert auch):

Code: Alles auswählen

auswahl = Profil.objects.filter(user__date_joined__lt=date(2023,8,1))
Das heißt ja wahrscheinlich, dass es mir gelungen ist von "User" auf "Profil" zuzugreifen, aber nicht umgekehrt.
Benutzeravatar
sparrow
User
Beiträge: 4195
Registriert: Freitag 17. April 2009, 10:28

Es ist äußerst ungünstig eine instanz von "Profil" an den Namen "user" zu binden, wenn es auch "User" gibt.
Aber das mit den Namen hatten wir ja schon oft.

Code: Alles auswählen

    # irgendwo weiter oben im Code:
    profil = Profil.objects.filter(...).select_related("user", "gruppe")

    startdatum = profil.gruppe.ab if profil.gruppe else profil.user.date_joined
Pitwheazle
User
Beiträge: 873
Registriert: Sonntag 19. September 2021, 09:40

Nun ja, das Kind ist jetzt ja aber nun mal schon in den Brunnen gefallen. Ich habe während des Schreibens ja erst Anfänge von Python und Django gelernt. Ich wage auch zu bezweifeln, dass mir das grundlegend besser gelingen würde, wenn ich von vorn anfangen würde.
Was kammt den in den Filter anstelle der Pünktchen? "user=user" geht nicht, da ich da immer noch nicht auf den "User" zugreife?

Code: Alles auswählen

Cannot query "28, Super Lehrer, lehrer": Must be "User" instance
Benutzeravatar
sparrow
User
Beiträge: 4195
Registriert: Freitag 17. April 2009, 10:28

Das kann dir hier niemand beantworten, weil aus deinem Post nicht hervorgeht, wo "user" bei dir her kommt.
Und dein "user" ist mein "profil".
Pitwheazle
User
Beiträge: 873
Registriert: Sonntag 19. September 2021, 09:40

Das ist das "User model" aus django.contrib.auth. Da sind die Felder "username", "password", "email" angelegt und "date_joined" wird wohl automatisch auch angelegt.
Benutzeravatar
sparrow
User
Beiträge: 4195
Registriert: Freitag 17. April 2009, 10:28

Dein "user" ist eine Instanz von Profil - nicht von User...
Deshalb habe ich dem einen vernünftigen Namen gegeben. Um genau diese Verwirrung zu verhindern.
Pitwheazle
User
Beiträge: 873
Registriert: Sonntag 19. September 2021, 09:40

Ja, das ist ja das Problem. Aber dieser user ist doch verbunden mit dem user aus der django.contrib.auth.
Pitwheazle
User
Beiträge: 873
Registriert: Sonntag 19. September 2021, 09:40

sparrow hat geschrieben: Dienstag 12. März 2024, 19:38 Deshalb habe ich dem einen vernünftigen Namen gegeben. Um genau diese Verwirrung zu verhindern.
kannst du das bitte für einen Dummie erklären?
Benutzeravatar
sparrow
User
Beiträge: 4195
Registriert: Freitag 17. April 2009, 10:28

Vergib! vernüftige! Namen!

Du hast in deinem ersten Beitrag geschrieben:

Code: Alles auswählen

user_gruppe = user.gruppe
USER.grupper <--- Das _user_ ist kein "User" sondern ein "Profil". Und das musst du ja irgendwann an den Namen gebunden haben.
So, und das habe ich in meinem Code "profil" genannt.
Da wo du dein "user" selektierst (das kein User ist), da wäre "select_related" richtig. Muss man nicht machen, macht man aber so.

Und wenn du das gleich vernünftig "profil" genantn hättest, dann wäre dir auch gleich aufgefallen, dass "Profil" kein "date_joined" Attribut hat.
Und dann ist der Schritt zu "profil.user" viel naheliegender als jetzt "user.user" zu schreiben. Weil das nach 4 Tagen niemand mehr nachvollziehen kann. Du ja auch nicht, wie sich hier zeigt.

Deshalb sind Namen so wichtig. Und deshalb erzählen wir das hier gebentsmühlenartig.
Pitwheazle
User
Beiträge: 873
Registriert: Sonntag 19. September 2021, 09:40

Das heißt, hier:

Code: Alles auswählen

def uebersicht(req, schueler_id=0):
    if req.user.is_authenticated:
        lehrer = User.objects.filter(pk=req.user.id, groups__name='Lehrer').exists()
        loeschen = False 
        if schueler_id == 0:
            user = get_object_or_404(Profil, user_id = req.user.id)
            if lehrer:
                loeschen = True            
        else:
            user = get_object_or_404(Profil, id = schueler_id
            ....)
und in der ganzen Funktion müsste ich "user" durch "profil" ersetzen? Macht irgendwie Sinn :).
Mal gespannt, ob ich es dann hinbekomme.
Pitwheazle
User
Beiträge: 873
Registriert: Sonntag 19. September 2021, 09:40

OK, das war nicht einfach - hat aber auf den ersten Blick geklappt. Eure häufigen Hinweise auf die Namen sind das eine, das Begreifen das andere. Mit dem "sj" und dem "hj" fand ich das nicht so überzeugen aber an diesem Beispiel war es jetzt sehr einleuchtend!
(Alledings war es jetzt aus dem imaneten Problem schwierig die verschiedenen "user" zu unterscheiden und dabei habe ich es dann aber (hoffentlich) begriffen.
Pitwheazle
User
Beiträge: 873
Registriert: Sonntag 19. September 2021, 09:40

Aber zunächst habe ich jetzt Verständnisprobleme, was genau "....select_related("user", "gruppe") macht.

Code: Alles auswählen

profil = get_object_or_404(Profil, user_id = req.user.id).select_related("user", "gruppe")
wirft den Fehler

Code: Alles auswählen

'Profil' object has no attribute 'select_related'
und dann habe ich auch noch das Problem, dass beim Erzeugen der Lerngruppe nur das Datum gespeichert wird

Code: Alles auswählen

ab = models.DateField(auto_now_add=True)
und für den User ein Datetime Object.
Und ich vergleiche es mit

Code: Alles auswählen

d0 = date(sj//100+2000,7,24)
Mir ist es gelungen, das in der Lerngruppe auf DateTimeField zu ändern dieses d= habe ich aber nicht hinbekommen

Code: Alles auswählen

d0 = datetime(sj//100+2000,7,24),0,0,0,0
spaeter = (d3 - d0).days//7

Code: Alles auswählen

can't subtract offset-naive and offset-aware datetimes

... das hatten wir doch schonmal? Mein Gedächtnis!
Pitwheazle
User
Beiträge: 873
Registriert: Sonntag 19. September 2021, 09:40

... und bevor ihr schimpft - ich habe

Code: Alles auswählen

gruppe.ab
ersetzt durch

Code: Alles auswählen

gruppe.erstellt_am
:)
Antworten