Query über 2 Tabellen und filter

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

Moin,

Ich möchte mit Django alle Datensätze aus dem Tab1, wobei alle Daten, die in Tab2 bereits vorhanden sind ausgeschlossen werden.

Code: Alles auswählen

class Tab1(models.Model):
    Mitglied = models.ForeignKey("Member", on_delete=models.CASCADE)
    Betrag1 = models.DecimalField(max_digits=5, decimal_places=2)
    Betrag2 = models.DecimalField(max_digits=5, decimal_places=2, blank=True, null=True)
    Begin = models.DateField()
    Ende = models.DateField(null=True, blank=True)
    

class Tab2(models.Model):
    Mitglied = models.ForeignKey("Member", on_delete=models.CASCADE)
    Jahr = models.IntegerField(max_length=4)
    Betrag = models.FloatField()
Ich benötige also alle Mitglieder aus Tab1, die nicht bereits im Tab2 enthalten sind.
Ich hab gerade so gar keine zündende Idee, wie ich mein Querry aufbauen muss.
Benutzeravatar
sparrow
User
Beiträge: 4237
Registriert: Freitag 17. April 2009, 10:28

Ich persönlich halte es immer für sehr schwierig, wenn man Beispiele verklausuliert statt einfach den Code zu nehmen, den man tatsächlich verwendet. Jedenfalls hoffe ich sehr, dass deine Modelle nicht "Tab1" und "Tab2" heißen.

Namen (außer die von Klassen [PascalCase] und Konstanten [KOMPLETT_GROSS]) schreibt man in Python klein_mit_unterstrich. Alle deine Feldnamen sind daher falsch geschrieben.

Dann benutzt du mal DecimalField für Beträge (was richtig ist) mal FloatField (was eher falsch ist).

Und dieses Denglish mag ich auch nicht.

Code: Alles auswählen

class Tab1(models.Model):
    member = models.ForeignKey("Member", on_delete=models.CASCADE, related_name=tab1s)
    amount1 = models.DecimalField(max_digits=5, decimal_places=2)
    amount2 = models.DecimalField(max_digits=5, decimal_places=2, blank=True, null=True)
    start = models.DateField()
    end = models.DateField(null=True, blank=True)
    

class Tab2(models.Model):
    member = models.ForeignKey("Member", on_delete=models.CASCADE, related_name=tab2s)
    year = models.IntegerField(max_length=4)
    amount = models.DecimalField(max_digits=5, decimal_places=2)
Dann würde es wahrscheinlich so gehen:

Code: Alles auswählen

remaining_members = Member.objects.filter(id__in=tab1s__member).exclude(id__in=tab2s__member)
guhamail
User
Beiträge: 16
Registriert: Samstag 19. Februar 2022, 13:34

Moin,

vielen Dank für deine Unterstützung.

Deine Kritik ist natürlich vollkommen berechtigt und es gibt keine Entschuldigung dafür, warum ich die Konventionen nicht beachtet habe. Also versuche ich gar nicht erst, eine Ausrede zu finden. Ich habe meine Models jetzt überarbeitet.

Mit deinem Lösungsvorschlag komme ich jedoch leider nicht klar. Ich habe versucht es in der Shell umzusetzen. Ich erhalte eine Fehlermeldung.

Code: Alles auswählen

NameError                                 Traceback (most recent call last)
Input In [24], in <cell line: 1>()
----> 1 tmp=Member.objects.filter(id__in=tab1s__member)

NameError: name 'tab1s__member' is not defined
Es wird also offensichtlich keine Verbindung zum Model tab1 hergestellt. Ich habe mit Hilfe der Doku versucht eine Lösung zu finden, muss aber passen. Was habe ich übersehen?
Benutzeravatar
sparrow
User
Beiträge: 4237
Registriert: Freitag 17. April 2009, 10:28

Den related_name hast du wie in meinem Beispiel gesetzt?
guhamail
User
Beiträge: 16
Registriert: Samstag 19. Februar 2022, 13:34

ja, habe ich.

Hier mal mein "Echt-Model"

Code: Alles auswählen


class Einzuege(models.Model):
    mitglied = models.ForeignKey("Mitglieder", on_delete=models.CASCADE, related_name="einzug")
    abteilung = models.ForeignKey("Abteilung", on_delete=models.CASCADE)
    jahr = models.IntegerField(max_length=4)
    betrag = models.DecimalField(max_digits=5, decimal_places=2)

und die Fehlermeldung:

Code: Alles auswählen

NameError                                 Traceback (most recent call last)
Input In [6], in <cell line: 1>()
----> 1 a=Mitglieder.objects.filter(id__in=einzug__mitglied)

NameError: name 'einzug__mitglied' is not defined

Antworten