2014-09-24 62 views
0

在我的Django項目中,我想顯示一些模型的列表(假設我們使用博客文章),默認情況下,顯示本月的帖子列表。不過,我也希望能夠顯示任意日期範圍內的所有帖子。Django基於類的視圖 - 任意日期範圍?

我看着MonthArchiveView,這完全符合我的第一要求,但我不認爲這會對我的第二個要求。

我也在尋找ArchiveIndexView(這看起來類似於ListView?),但我不確定是否容易做到我想要的。

有沒有人有任何建議?內置的通用視圖能夠做我正在尋找的東西,還是應該繼續寫下我自己的?

謝謝!

+0

我愛Django的意見,而不是基於類的。 – doniyor 2014-09-24 20:55:33

+0

日期視圖被設計爲按固定時間段分塊並支持導航鏈接,如'上個月' - 如果我使用基於類的通用視圖,我可能會使用'ListView'來完成此操作。 – 2014-09-24 21:28:11

回答

0

所以這裏的答案是創建一個自定義的CBV。我已經完成了,這是ListView的一個孩子,從DateMixin和BaseDateListView類中獲得了一些靈感。代號將維持here但後人低於包括:

class ArbitraryDateListView(ListView): 
    date_field = None 
    date_format = '%Y-%m-%d' 
    since_date = None 
    until_date = None 
    auto_until_date = False 

    def get_date_field(self): 
     if self.date_field is None: 
      raise ImproperlyConfigured("%s.date_field is required." % self.__class__.__name__) 
     return self.date_field 

    def get_date_format(self): 
     """ 
     Get a date format string in strptime syntax to be used to parse the date from url variables. 
     """ 
     return self.date_format 

    def get_since_date(self): 
     """ 
     Return the start date for which this view should display data 
     """ 
     since_date = self.since_date 
     if since_date is None: 
      try: 
       since_date = self.kwargs['since'] 
      except KeyError: 
       try: 
        since_date = self.request.GET['since'] 
       except KeyError: 
        raise Http404("No since date specified") 
     format = self.get_date_format() 
     return datetime.datetime.strptime(since_date, format).date() 

    def get_until_date(self): 
     """ 
     Return the end date for which this view should display data 
     """ 
     until_date = self.until_date 
     if until_date is None: 
      try: 
       until_date = self.kwargs['until'] 
      except KeyError: 
       try: 
        until_date = self.request.GET['until'] 
       except KeyError: 
        if self.auto_until_date: 
         return self.get_until_date_from_since_date() 
        else: 
         raise Http404("No until date specified") 
     format = self.get_date_format() 
     return datetime.datetime.strptime(until_date, format).date() 

    def get_until_date_from_since_date(self): 
     """ 
     Return a calculated end date from start date when end date is not provided 
     """ 
     if self.auto_until_date: 
      raise NotImplementedError("If auto_util_date=True, get_until_date_from_since_date must be implemented") 

    def get_queryset(self): 
     queryset = super(ArbitraryDateListView, self).get_queryset() 
     date_field = self.get_date_field() 
     since = self.get_since_date() 
     until = self.get_until_date() 
     lookup_kwargs = { 
      '%s__gte' % date_field: since, 
      '%s__lt' % date_field: until, 
     } 
     queryset = queryset.filter(**lookup_kwargs).order_by('-%s' % date_field) 
     return queryset 

    def get_context_data(self, **kwargs): 
     context = {'since': self.get_since_date(), 
        'until': self.get_until_date()} 
     context.update(kwargs) 
     return super(ArbitraryDateListView, self).get_context_data(**context) 
0

您可以使用從ListView擴展的類並設置上下文覆蓋父級方法。在這個方法裏面,你可以調用一個函數來過濾你需要的對象。 您可以在documentation中看到示例。

此外,爲了獲得對象,在一些數據的日期範圍我做這樣的事情:

def get_objects_in_some_range(self): 
     now = datetime.now() 
     current = self.filter(end_date__gte=now) 
     current = current.filter(start_date__lte=now) 
     return current 

你可以通過它的一些參數進行過濾你想要的日期。