22

Djangoフィルターで以下を論理的に表現するのに苦労しています。「イベント」モデルとロケーションモデルがあり、次のように表すことができます。

class Location(models.Model):
    name = models.CharField(max_length=255)

class Event(models.Model):
    start_date = models.DateTimeField()
    end_date = models.DateTimeField()
    location = models.ForeignKeyField(Location)

    objects = EventManager()

特定の場所について、今日発生するすべてのイベントを選択したいと思います。EventManagerの「bookings_today」メソッドを介してさまざまな戦略を試しましたが、正しいフィルター構文ではわかりません。

class EventManager(models.Manager):
    def bookings_today(self, location_id):
        bookings = self.filter(location=location_id, start=?, end=?)

date()は時間をゼロにするため失敗し、日中の時間はアプリにとって重要です。同じことが日付の最小値と最大値にも当てはまり、それらをブックエンドとして使用します。さらに、複数の有効な構成が考えられます。

start_date < today, end_date during today
start_date during today, end_date during today
start_date during today, end_date after today

さまざまなオプションのセット全体をコーディングする必要がありますか、それともよりシンプルでエレガントな方法がありますか?

4

7 に答える 7

37

datetime2つの異なるしきい値が必要になります-today_starttoday_end

from datetime import datetime, timedelta, time

today = datetime.now().date()
tomorrow = today + timedelta(1)
today_start = datetime.combine(today, time())
today_end = datetime.combine(tomorrow, time())

今日起こっていることはすべて、 today_end に始まり、後 に終わったに違いありませんtoday_start

class EventManager(models.Manager):
    def bookings_today(self, location_id):
        # Construction of today_end / today_start as above, omitted for brevity
        return self.filter(location=location_id, start__lte=today_end, end__gte=today_start)

(PS DateTimeField(ではなくDateField)が呼び出されることは、foo_date苛立たしい誤解を招く可能性があります-公正startに検討してくださいend...)

于 2012-06-29T15:15:00.037 に答える
13

私が見た答えはどれもタイムゾーンを認識していません。

代わりにこれを実行してみませんか:

from django.utils import timezone

class EventManager(models.Manager):
    def bookings_today(self, location_id):
        bookings = self.filter(location=location_id, start__gte=timezone.now().replace(hour=0, minute=0, second=0), end__lte=timezone.now().replace(hour=23, minute=59, second=59))
于 2018-03-04T11:52:15.113 に答える
7

次のような範囲を使用する必要があります。

class EventManager(models.Manager):
    def bookings_today(self, location_id):
        from datetime import datetime
        now = datetime.now()
        bookings = self.filter(location=location_id, start__lte=now, end__gte=now)
        return bookings
于 2012-06-28T13:22:16.920 に答える
4

timezone.localtime(timezone.now()).date()正しい日付を取得します。

今日(start今日)発生するイベントを取得するには:

from django.utils import timezone

class EventManager(models.Manager):
    def bookings_today(self, location_id):
        t = timezone.localtime(timezone.now())
        bookings = self.filter(location=location_id, start__year = t.year,
            start__month = t.month, start__day = t.day, )
于 2018-11-23T08:41:06.570 に答える
1

これはどうですか:pub_date__gte=datetime(2005, 1, 1)_gteとを使用し__lteて、連鎖方式を使用して1日以内に開始と終了を制限します。

多分のようなものself.filter(start__gte=datetime(2005, 1, 1)).filter(end__lte=datetime(2005, 1, 1))lte以下をgte表し、以上を表します。

djangodocにあります。

于 2012-06-28T13:20:37.720 に答える
1

除外はここにいるあなたの友達だと思います!

today = datetime.date.today()
tomorrow = today + datetime.timedelta( days = 1 )
self.filter( location = location_id ).exclude( end_date__lt = today ).exclude( start_date__gte = tomorrow )
于 2012-06-29T10:35:36.897 に答える
1

提案があります

class Car:
      name = models.CharField()
      launched_date = models.DateTimeField()

今日の日付で日時フィールドをフィルタリングすることは非常に困難です。timezone.now()を使用しても、正しい出力は得られません。timezone.now()にも時間があります。

datetimeフィールドには時刻が含まれているため、正しい日付を指定しても時刻は一致しません。

それで

日付に基づくフィルタリングにはdatefieldを使用することをお勧めします

class Car:
      name = models.CharField()
      launched_date = models.DateField()

質問への回答:-

   from django.utils.timezone import datetime 
    today = datetime.today()
    events_for_today = Event.objects.filter(start_date__year=today.year,
                        start_date__month=today.month,
                         start_date__day=today.day)
于 2021-05-20T10:19:38.760 に答える