3 Stimmen

Django holt Modellobjekte basierend auf Zeit mit Intervall auf dem Modell selbst

Ich versuche, alle abgelaufenen Objekte für ein Modell in meiner Django-Anwendung abzurufen.

Das Modell sieht wie folgt aus:

MyModel(models.Model):
    owner = models.ForeignKey(User)
    last_check = models.DateTimeField(blank=True, null=True)
    interval = models.IntegerField(default=1800)

Ich muss alle übereinstimmenden Objekte abrufen, bei denen last_check kleiner als jetzt minus das Prüfintervall ist, um festzustellen, ob das Objekt erneut geprüft werden sollte.

Kein Problem, wenn ich ein statisches Intervall verwende:

time_diff = datetime.now() - timedelta(seconds=1800)
MyModel.object.filter(last_check__lte=time_diff)

Aber wenn sich das Intervall auf dem Modell selbst befindet, kann ich nicht herausfinden, wie man es macht. Dies ist, was ich versucht habe:

objects_to_check = MyModel.objects.filter(
                                        last_check__isnull=False
                                    ).filter(
                                        last_check__lte=datetime.now() - timedelta(seconds=F('interval'))
                                    )

Aber das funktionierte überhaupt nicht, ich bekam nur folgende Fehlermeldung

unsupported type for timedelta seconds component: F

Haben Sie eine Idee, wie man das Problem lösen kann?

3voto

Andriy Drozdyuk Punkte 53902

Hm... Ich bin mir nicht sicher, ob Sie den Wert des Feldes, in dem gesucht wird, ändern können. Die Datenbank müsste den Wert zuerst abrufen, die Funktion timedelta darauf anwenden und dann einen Vergleich durchführen.

Ich denke, Sie sollten Ihre Architektur überdenken... aber ich könnte mich irren. Vielleicht sollten Sie statt der Speicherung von last_check, die Abgelaufen Eigenschaft, die Sie direkt überprüfen können:

MyModel.objects.filter(expired__lte=current_date)

und dann bei der Aktualisierung des Modells:

def save(self):
    self.expired = datetime.now() + self.interval;

oder so ähnlich.

0voto

Dmitry Risenberg Punkte 2231

F Objekt steht für einen Verweis auf ein Modellfeld in der Datei SQL-Abfrage und kann daher nicht zur Initialisierung eines Python-Objekts verwendet werden. Sie können datenbankspezifische Abfragen schreiben, indem Sie extra Methode oder filtern Sie sie einfach auf Python-Ebene:

filter(lambda x: x.last_check <= datetime.now() - timedelta(seconds = x.interval), MyModel.objects.all())

-1voto

turingmachine Punkte 489

Die Unterstützung für diese Art von Abfragen ist in Arbeit: http://code.djangoproject.com/ticket/10154

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X