model filter zeigt unerwartetes Verhalten

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

Die Lehrer können Lerngruppen anlegen und die Schüler sich dort anmelden. im entsprechenden admin Bereich habe ich einen Filter auf "lehrer" erstellt. In meinem Adminzugang, bekomme ich bei den Filtermöglichkeiten auch die angemeldeten Schüler angezeigt - das sollte doch nicht so sein oder?

Code: Alles auswählen

class Lerngruppe(models.Model):
    lehrer = models.ForeignKey(User, null=True, on_delete=models.CASCADE, related_name='gruppe')
    name = models.CharField(max_length=15)
    
    class Meta:
        verbose_name_plural = 'Lerngruppen'
        unique_together = ['lehrer', 'name']
    
    def __str__(self):
        return f"{self.name}, {self.lehrer}"
hier wird der Link der Schüler auf die Lerngruppe gespeichert:

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)
    
    klasse = models.CharField(max_length=10)
    # diese Felder werden erst ausgefüllt, wenn ein Schüler seine Lerngruppe wählt
    schule = models.ForeignKey(Schule, null= True, blank=True, on_delete = models.SET_NULL)
   gruppe = models.ForeignKey(Lerngruppe, null= True, blank=True, on_delete = models.SET_NULL, related_name='gruppe'
    
    jg = models.PositiveSmallIntegerField(validators=[MinValueValidator(1), MaxValueValidator(10)])
    kurs= models.CharField(max_length=1, choices=wahl_kurs.choices, default=wahl_kurs.E_KURS,)

    # werden beim Erstellen eingestellt
    stufe = models.PositiveSmallIntegerField(default=5) #, editable=False)
    sj = models.SmallIntegerField(default=0)
    hj = models.SmallIntegerField(default=0)

    katmax = models.IntegerField(default=0)                                 # die Zeilennummer die höchsten gewählten Aufgabenkategorie
    #voreinst = models.IntegerField(default=1)                               # hier können Voreinstellungen gesetzt und abgefragt werden
    voreinst = models.JSONField(blank=True, null=True, default=dict)

    #richtig = models.JSONField()                                            # hier werden die Anzahl der richtigen Aufgaben je Kategorie für die Lehrerübersicht gespeichert
    #quote = models.JSONField()                                              # und hier die entsprechenden Fehlerquoten

    def __str__(self):
        return f"{self.vorname} {self.nachname}, {self.klasse}"

    class Meta:
        verbose_name = 'Profil'
        verbose_name_plural = 'Profile'
und das ist der Code in admin.py:

Code: Alles auswählen

from django.contrib import admin
from .models import   Ort, Schule, Profil, Lerngruppe

class LerngruppeAdmin(admin.ModelAdmin):
    list_filter=("lehrer", )

admin.site.register(Profil)
admin.site.register(Lerngruppe, LerngruppeAdmin)
Benutzeravatar
sparrow
User
Beiträge: 4164
Registriert: Freitag 17. April 2009, 10:28

Mit list_filter sagst du nur, dass du in der Listenansicht im Admin-Bereich einen Filter auf das Feld "lehrer" angezeigt haben möchtest. Der ist (im Standard) rechts an der Seite und erlaubt es dem Benutzer nach diesem Feld zu filtern.

Oder verstehe ich deine Frage falsch?
Pitwheazle
User
Beiträge: 869
Registriert: Sonntag 19. September 2021, 09:40

Ja genau. Der Filter wird auch angezeigt, aber hier sind nicht nur die Lehrer sondern auch die Schüler, die mit diesen Lerngruppen verknüpft sind, gelistet. Wenn ich auf einen Lehrer klicke, bekomme ich auch seine Lerngruppen. Beim Klick auf einen Schülername eine leere Liste (wie erwartet).
Benutzeravatar
sparrow
User
Beiträge: 4164
Registriert: Freitag 17. April 2009, 10:28

Ah.
Ich bin mir ziemlich sicher, dass du nicht die Schüler angezeigt bekommst, die verknüpft sind. Du bekommst alle User angezeigt, oder?

Wenn du nur die Lehrer in der Auswahl des Filters haben möchtest, dann musst du schauen, wie du einen Filter mit einem Queryset als Quelle anlegen und dann nur die Lehrer selektierst.
Pitwheazle
User
Beiträge: 869
Registriert: Sonntag 19. September 2021, 09:40

Nun ja, wahrscheinlich schon. Ich dachte, diese Einstellung in meinem admin.py macht genau dieses. Im model sind ja nur die Lehrer eingetragen.
Pitwheazle
User
Beiträge: 869
Registriert: Sonntag 19. September 2021, 09:40

sparrow hat geschrieben: Donnerstag 2. Februar 2023, 16:24 Ah.
Ich bin mir ziemlich sicher, dass du nicht die Schüler angezeigt bekommst, die verknüpft sind. Du bekommst alle User angezeigt, oder?
Wenn du nur die Lehrer in der Auswahl des Filters haben möchtest, dann musst du schauen, wie du einen Filter mit einem Queryset als Quelle anlegen und dann nur die Lehrer selektierst.
Kannst du mir da bitte nochmals auf die Sprünge helfen?
Ich habe mich nochmals mit meinem Tutorial beschäftigt und dort wird gezeigt, dass, wenn ich in admin.py

Code: Alles auswählen

class LerngruppeAdmin(admin.ModelAdmin):
    list_filter=("lehrer", )
admin.site.register(Lerngruppe, LerngruppeAdmin)
und in meinen models:

Code: Alles auswählen

class Lerngruppe(models.Model):
    lehrer = models.ForeignKey(User, null=True, on_delete=models.CASCADE, related_name='gruppe')
    name = models.CharField(max_length=15)
steht, eigentlich nur die Einträge im Feld "lehrer" angezeigt werden dürften.
Ich hab ja auch in anderen models das genutzt und da funktioniert es ohne weiteres Zutun. Was ist hier anders?
Benutzeravatar
sparrow
User
Beiträge: 4164
Registriert: Freitag 17. April 2009, 10:28

Ich kann dir nicht sagen, was du für ein Tutorial liest, aber ich kann dir sagen: Der Filter, so wie du ihn anwendest, zeigt alle User an.

Für dich nachgebaut:

Code: Alles auswählen

from django.contrib import admin
from .models import Lerngruppe

class LerngruppeAdmin(admin.ModelAdmin):
    list_filter=("lehrer", )

admin.site.register(Lerngruppe, LerngruppeAdmin)
Bild

Wie du siehst:
Keine Lerngruppe (also kann auch kein Lehrer zugeorndet sein) - aber der Benutzer "admin" in der Auswahl für den Filter.
Benutzeravatar
sparrow
User
Beiträge: 4164
Registriert: Freitag 17. April 2009, 10:28

Das sollte dein Problem lösen:

Code: Alles auswählen

    list_filter=(
        ("lehrer", admin.RelatedOnlyFieldListFilter), 
    )
Und das hier ist vielleicht lesenswert.
Der Filter an sich wird aber irgendwann für dich unbrauchbar. Spätestens, wenn du Erfolg hast und dann da xhundert Namen stehen.
Pitwheazle
User
Beiträge: 869
Registriert: Sonntag 19. September 2021, 09:40

sparrow hat geschrieben: Freitag 3. Februar 2023, 19:11 Das sollte dein Problem lösen:

Code: Alles auswählen

    list_filter=(
        ("lehrer", admin.RelatedOnlyFieldListFilter), 
    )
Danke, das funktioniert.
sparrow hat geschrieben: Freitag 3. Februar 2023, 19:11 Und das hier ist vielleicht lesenswert.
Und das habe ich jetzt auch kapiert, nochmals Danke. In meinen anderen Filtern war zwar auch ein foreignkey auf "Kategorien", da ist das aber nicht aufgefallen, da es ja nur 14 gibt und diese auch alle relevant sind.
sparrow hat geschrieben: Freitag 3. Februar 2023, 19:11 Der Filter an sich wird aber irgendwann für dich unbrauchbar. Spätestens, wenn du Erfolg hast und dann da xhundert Namen stehen.
Das nehme ich gerne in Kauf - ich denke aber auch dann ist es hilfreich. Außerdem kann ich dann ja noch nach Schulen und Orten filtern.
Antworten