2012-05-09 66 views
10

我有一個模型,其中包含datefield。我試圖獲取包含當前周的該模型的查詢集(從星期一開始)。Django的queryset過濾ISO周編號

如此以來,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

我不知道,如果ORM的支持,但你可以回退原始查詢,如果它不https://docs.djangoproject.com/en/dev/topics/db/sql/ – dm03514

+0

我知道這個選項dm03514,但我寧願寫我自己的過濾器,然後。這也是一個選項,但我要求知道也許有可能在Django中使用默認動作來實現這一點,而不用擴展它。 – JackLeo

+1

順便說一句,有很好的python dateutil模塊,可能會有所幫助http://pypi.python.org/pypi/python-dateutil – aisbaa

回答

8

你不能這樣做。請記住,它不僅僅是Python支持的問題,Django必須將過濾器傳遞給數據庫,並且數據庫不支持如此複雜的日期計算。您可以使用使用__range,但開始日期和結束日期。

+0

是的,我也會使用* __範圍*,也許事件添加自定義模型管理器和自定義Queryset與*周( date_field =(2012,18))*方法。 – aisbaa

+0

我知道範圍選項,但由於要獲得一週的兩端所需的動作次數,我避開了它,但我想這可能是更小的罪惡。非常感謝。 – JackLeo

+1

是的,不是你的應用程序的每個部分都需要代碼高爾夫資格。有時你需要走更長的路。總是做最簡單,最明顯的,並創建最少的腳印(修改Django如何處理過濾器會留下相當大的佔用空間)。 –

1

(這個答案應該只用於Postgres的工作,但對於其他數據庫可能會奏效。)

此問題的一個快速而優雅的解決辦法是定義這兩個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對象使用的Postgres EXTRACT function,其中s支持weekisoyear

0

ExtractWeek已在Django 1.11中引入,用於基於isoweek數字進行過濾。

對於Django 1。10個較低的版本,下面的解決方案通過異數星期Postgres數據庫適用於過濾:

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

現在做查詢,如下所示

queryset.annotate(week=ExtractWeek('date'))\ 
      .filter(week=week_number) 
相關問題