2012-07-10 65 views
2

我有一個自定義管理器模型,目的是過濾「活動」對象,即對象的start_date低於當前時間和end_date大於當前時間。Tastypie資源沒有顯示新創建的對象(日期過濾問題)

這是我models.py相關部分:

from django.utils.timezone import now 

class ActiveObjectManager(models.Manager): 
    def get_query_set(self): 
     return super(ActiveObjectManager, self).get_query_set().\ 
      filter(start_date__lt=now(), end_date__gt=now()) 

class Object(models.Model): 
    start_date = models.DateTimeField(_('Service start date'), \ 
     auto_now_add=False, null=False, blank=False) 
    end_date = models.DateTimeField(_('Service end date'), auto_now_add=False, \ 
     null=False, blank=False) 
    ... 
    objects = models.Manager() 
    objects_active = ActiveObjectManager() 

該管理整個應用程序,並在Django殼的偉大工程。但是,如果我在管理界面中創建一個對象,並將start_date設置爲「now」選擇器,則tastypie提供的API不會顯示此新創建的對象(儘管它確實顯示較舊的對象)。管理員列表正確顯示新對象處於活動狀態。

這是我api.py的相關部分:

from app.models import Object 

class ActiveObjectResource(ModelResource): 
    modified = fields.BooleanField(readonly=True) 

    class Meta: 
     resource_name = 'activeobjects' 
     queryset = Object.objects_active.all() 

我強烈懷疑的是,作爲類ActiveObjectResource被解釋一次,只執行一次夫妻now()呼叫,即API子系統始終呼叫filter(),參數start_date__ltend_date__gt的參數值相同(在運行manage.py runserver後立即由now()返回的值)。

當我在資源類中的濾波權這樣這個問題仍然存在,甚至:

class ActiveObjectResource(ModelResource): 
    ... 
    class Meta: 
     queryset = Object.objects.\ 
      filter(start_date__lt=now(), end_date__gt=now()) 

而且,問題仍然存在,如果我通過可調用這樣的:

class ActiveObjectResource(ModelResource): 
    ... 
    class Meta: 
     queryset = Object.objects.filter(start_date__lt=now, end_date__gt=now) 

是否有我可以重寫ActiveObjectManagerActiveObjectResource來克服這個問題嗎?

更新: OK,看來我需要重寫get_object_list實現per-request alterations to the queryset,如:

class ActiveObjectResource(ModelResource): 
    class Meta: 
     queryset = Object.objects.all() 

    def get_object_list(self, request): 
     return super(MyResource, self).get_object_list(request).\ 
      filter(start_date__lt=now, end_date__gt=now) 

可是,我討厭重複這種邏輯的時候,我已經在模型級別有​​一個自定義的經理爲我做這個工作。

所以我的問題是:如何使用我的自定義模型管理器從我的ModelResource

+0

我在黑暗中拍攝在這裏,因爲我不是100%肯定這一點。不過,我的猜測是,由於多次調用'Object.active_objects.all()'在技術上仍然是*相同的查詢集,所以查詢緩存正在發揮作用。與此同時,'Object.objects.filter(...)'表面上顯然是一個不同的查詢,因此每次調用時都會使查詢緩存失效。 – 2012-07-10 14:42:50

+0

@ChrisPratt根據'get_query_set'中定義的內容,對'Object.active_objects.all()'的多次調用產生不同的查詢集,並且通過在shell中手動調用該管理器按預期工作來證明這一點。問題是'Object.active_objects.all()'被稱爲_only once_。 – Chewie 2012-07-10 16:42:10

+0

我已經更新了我的答案 – DataGreed 2012-07-20 07:49:53

回答

3

那麼,關於queryset在ModelResource.Meta。這裏是excerpt from the tastypie documentation

如果你放置任何可調對象在這,他們只會被評估一次(當Meta類被實例化時)。這尤其影響與日期/時間相關的事物。請參閱:ref:cookbook來解決這個問題。

it goes這裏:

一個常見的圖案需要的東西每個請求例如日期/時間改變,以限制查詢集。你可以通過輕微修改來實現這一點get_object_list

所以,是的,似乎唯一的方法來實現你想要做的是聲明get_object_list

新更新:因爲get_object_list只是一個return self._meta.queryset._clone(),嘗試類似的東西:

class ActiveObjectResource(ModelResource): 
    class Meta: 
     queryset = Object.objects_active.all() 

    def get_object_list(self, request): 
     return Object.objects_active.all() 
+0

是的,這正是我最終做的,有點。我這樣做:'self._meta.queryset = NewsGroup.objects_active.all();返回超級(NewsGroupAssignationResource,self).get_object_list(request)'。這有點怪異('Meta.queryset'的值完全沒用),但完成了工作。 – Chewie 2012-07-20 11:20:14