[Django] Effizienter Test auf Enthaltensein?

Sockets, TCP/IP, (XML-)RPC und ähnliche Themen gehören in dieses Forum
Antworten
sma
User
Beiträge: 3018
Registriert: Montag 19. November 2007, 19:57
Wohnort: Kiel

Ich habe einen Container und ein Item.

Code: Alles auswählen

class Container(models.Model):
    pass

class Item(models.Model):
    containers = models.ManyToManyField(Container, related_name='items')
Nun möchte ich feststellen, ob ein Item in einem bestimmten Container steckt. Naiv wie ich bin, dachte ich mir, ein

Code: Alles auswählen

if item in container.items: ...
wird's schon richten, aber das geht nicht. Auch ein

Code: Alles auswählen

if item in container.items.all(): ...
ist nicht, was ich will, denn das holt und instantiiert alle Items, um sie dann abzulaufen. Das ist extrem ineffizient.
Die folgende Zeile macht's besser, aber geht das nicht einfacher? Übersehe ich das offensichtliche?

Code: Alles auswählen

if container.items.filter(id=item.id).count() > 0: ...
Stefan
.robert
User
Beiträge: 274
Registriert: Mittwoch 25. April 2007, 17:59

item.id und container.id sind doch bekannt, oder?
Warum nicht einfach

Code: Alles auswählen

if item.objects.get(id=itemid).containers.filter(id__exact=containerid).count() > 0: ...
(ungetestet)
sma
User
Beiträge: 3018
Registriert: Montag 19. November 2007, 19:57
Wohnort: Kiel

@.robert Einfach? Dein Ausdruck ist ja noch länger als meiner :) Und beide haben den Nachteil, dass sie das gesamte Objekt unnötigerweise laden. Dies kann man, wie ich inzwischen recherchiert habe, mit einem weiteren .values('id') vermeiden, dennoch finde ich die Existenzprüfung so wichtig, dass ich mir da eigentlich im QuerySet-Objekt eine fertige Methode für gewünscht hätte. Python kennt ja den `in`-Operator. Warum wurde da nicht einfach `__contains__` entsprechend implementiert? Vielleicht mache ich dafür mal einen Patch...

Stefan
Benutzeravatar
jens
Python-Forum Veteran
Beiträge: 8502
Registriert: Dienstag 10. August 2004, 09:40
Wohnort: duisburg
Kontaktdaten:

Stell mal die Frage auf der django Mailingliste.

GitHub | Open HUB | Xing | Linked in
Bitcoins to: 1JEgSQepxGjdprNedC9tXQWLpS424AL8cd
Antworten