基于Django类的视图 - 任意日期范围?

时间:2014-09-24 20:49:57

标签: django django-class-based-views

在我的Django项目中,我想显示一些模型的列表(假设,让我们使用博客文章),默认情况下,显示本月的帖子列表。但是,我还希望能够显示任意日期范围之间的所有帖子。

我正在看MonthArchiveView,这完全符合我的第一个想要,但我不认为这是我的第二次。

我也在看ArchiveIndexView(看起来与ListView类似?)但是我不确定这是否能够轻松实现我的目标。

有人有任何建议吗?内置的通用视图是否能够满足我的需求,或者我应该继续编写自己的视图?

谢谢!

2 个答案:

答案 0 :(得分: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

你可以传递一些参数来过滤你想要的日期。

答案 1 :(得分: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)