2012-05-09 9 views
10

datefieldというモデルがあります。私は今週(月曜日に開始)を含むそのモデルのクエリセットを取得しようとしています。ISOの週番号によるDjangoクエリーセットのフィルタリング

だからDjango datefieldにはdatetime.dateというモデルが含まれているので、.isocalendar()を使ってフィルタリングすると仮定しました。論理的には、現在の週の日までに余分な比較や計算をすることなく、正確に私が望むものです。

それでは、私は基本的にやりたいことは、このロジックで動作するように力.filter文です:

if model.date.isocalendar()[2] == datetime.date.today().isocalendar()[2] 
    ... 

フィルタステートメントの内側にそれを書くことしかし、どうやって? .filter(model__date__isocalendar=datetime.date.today().isocalendar())は間違った結果を出すでしょう(今週ではなく今日と比較して同じです)。私は他の曜日オプションを気づいていない掘り真http://docs.python.org/library/datetime.htmlとして

...ドキュメントから

注:

date.isocalendar()3要素のタプルを返し、(ISO年、ISO週番号、ISO 平日)。

更新:

私は範囲を使用しての溶液を嫌い、まだそれが最良の選択肢ですが。 私の場合は、今週の試合を探しているので、週の始まりを示す変数を作成して、それよりも大きいか等しい値を表示します。週数を指定する場合は、両端が必要です。

today = datetime.date.today() 
monday = today - datetime.timedelta(days=today.weekday()) 

... \ 
.filter(date__gte=monday) 
+0

を次のように

from django.db.models.functions import Extract from django.db import models @models.DateTimeField.register_lookup class ExtractWeek(Extract): lookup_name = 'week' 

は今が、あなたがフォールバックすることができますORMサポート場合、私は知らないクエリを実行します – dm03514

+0

私はこのオプションdm03514を認識していますが、自分でフィルタを作成したいと思います。これもオプションですが、拡張せずにDjangoのデフォルトアクションを使用してこれを実現することが可能かどうかを知りたいと思っています。 – JackLeo

+1

btw便利なpython dateutilモジュールがありますhttp://pypi.python.org/pypi/python-dateutil – aisbaa

答えて

8

これはできません。 Pythonがサポートしているものだけではなく、Djangoはフィルタをデータベースに伝えなければならず、データベースはそのような複雑な日付計算をサポートしていません。ただし、です。ただし、開始日と終了日は__rangeです。

+0

はい、私も* __ range *を使用します。多分、イベントはカスタムModelManagerとカスタムQuerysetを* week( date_field =(2012、18))*メソッド。 – aisbaa

+0

私は範囲のオプションについて知っていますが、私は週の両方の終わりを得るために必要なアクションカウントのためにそれを避けていましたが、それはもっと悪いことかもしれないと思います。ありがとうございました。 – JackLeo

+1

ええ、あなたのアプリのすべての部分がコードゴルフに適格である必要はありません。場合によっては、より長い道のりをとらなくてはなりません。最もシンプルで最も明白なことを常に行い、フットプリントを最小限に抑えます(Djangoがフィルタを処理する方法を変更するとかなり大きなフットプリントが残ってしまう)。 –

1

(この答えは唯一のpostgresのために働く必要がありますが、他のデータベースのために働くかもしれません。)

この問題の迅速かつエレガントなソリューションは、これら2つのcustom transformersを定義するには、次のようになります。

from django.db import models 
from django.db.models.lookups import DateTransform 

@models.DateTimeField.register_lookup 
class WeekTransform(DateTransform): 
    lookup_name = 'week' 


@models.DateTimeField.register_lookup 
class ISOYearTransform(DateTransform): 
    lookup_name = 'isoyear' 

このように一週間で問い合わせることができます:

from django.utils.timezone import now 
year, week, _ = now().isocalendar() 

MyModel.objects.filter(created__isoyear=year, created__week=week) 

尻のシーンは、DjangoのDateTransformオブジェクトは、Sは、postgresのEXTRACT functionを使用していますweekおよびisoyearをサポートします。

0

ExtractWeekはisoweek番号に基づいてフィルタリングするためにDjango 1.11で導入されました。

Django 1の場合。解決策は、Postgresデータベース上のISO数週間でフィルタリングのために働き、次の10と下のバージョン、:

queryset.annotate(week=ExtractWeek('date'))\ 
      .filter(week=week_number) 
関連する問題