6

私はこのようなモデルに遭遇しました:

class Task(models.Model):
    timespan = models.IntegerField(null=True, blank=True)

class Todo(models.Model):
    limitdate = models.DateTimeField(null=True, blank=True)
    task = models.ForeignKey(Task)

今日の日付+関連モデルで定義された期間以下のすべてTodosを抽出する必要があります。limitdateTask

(ダミーの例)のようなもの:

today = datetime.datetime.now()
Todo.objects.filter(limitdate__lte=today + F('task__timespan'))

今、私はループでそれを行うことができますが、私はそれを行う方法を探していますF()、そして私はそれを見つけることができません。

でそれができるかどうか疑問に思い始めていF()ます。多分私は使うべきextraですか?

モデルコードを変更する余裕がないことに注意してください。

4

2 に答える 2

6

主な問題は、DBがサポートしておらずdate + integer、ORMクエリを書き込むのが難しいことdate + integer::intervalです。たとえばPostgreSQLの場合、は日数で表しintegerた列の値です。task_timespan

ただし
limitdate <= today + task__timespan
limitdate - today <= task__timespan

クエリを次のように変換できます

Todo.objects.filter(task__timespan__gte=F('limitdate') - today).distinct()

したがって、SQLはのようなものになります。これは、日数と比較できる出力がカウントされるinteger >= date - dateため、PostgreSQLで機能するはずです。date - dateintervalinteger

SqLiteなどの他のDBでは、最初に日付をキャストする必要があるため、複雑です...そして、正しいSQLを取得するために、またはそれjulianday()を再生する必要があると思います。extra()raw()

また、Chris Prattが示唆しているように、すべての相対フィールドでタイムスタンプを使用できる場合は、加算と減算の操作が制限されていないため、クエリタスクが簡単になる可能性があります。

PS私は今それを確認するためのenvを持っていません、あなたは最初にそれを試すことができます。

于 2012-09-17T15:34:31.640 に答える
2

問題は、データベースに TIMESPAN 型がないことです。したがって、Fこのコンテキストで実際に作業できるものを返すことはできません。データベースで実際に使用したフィールドのタイプはわかりませんが、これを行う唯一の方法は、タイムスパンを秒からなる整数として保存し、それをタイムスタンプとして「今日」に追加することです。と比較するために使用できる日時に変換しますlimitdate。ただし、Django がこのような複雑なロジックを で受け入れるかどうかはわかりませんF

于 2012-09-17T14:36:44.793 に答える