django-filter上的daterange

时间:2015-05-21 06:54:56

标签: python django django-rest-framework django-filters

我使用Django,Django REST Framework加上django-filters(alex / django-filter)。

我有一个带有字段start_date和end_date的模型,我正在尝试构建一个日期api-endpoint,它应该接收一个日期并回复其中的项目(start_date< date)和(end_date> date)。 有一个日期范围过滤器(https://django-filter.readthedocs.org/en/latest/ref/filters.html#daterangefilter),但我无法弄清楚如何使用它。到目前为止,这是我的代码:

urls.py:

url(r'^api/sales/$', views.SaleItemList.as_view(), name='sales'),

views.py:

class SaleItemFilter(django_filters.FilterSet):
    city = django_filters.CharFilter(name='trade_item__vendor__city')
    title = django_filters.CharFilter(name='trade_item__title')
    date = django_filters.DateRangeFilter()

    class Meta:
        model = SaleItem
        fields = ['sale_price', 'sale_date_start', 'sale_date_end', 'trade_item']

class SaleItemList(generics.ListAPIView):
    queryset = SaleItem.objects.all()
    serializer_class = SaleItemListSerializer
    filter_class = SaleItemFilter

serializers.py:

class SaleItemListSerializer(serializers.ModelSerializer):
    class Meta:
        model = SaleItem
        fields = ("sale_price", "sale_date_start", "sale_date_end", "trade_item", "slogan")

到目前为止我可以过滤确切的日期:

/ API /销售/?sale_date_start = 2015年5月22日

4 个答案:

答案 0 :(得分:13)

我不能谈论你的问题的Django REST Framework部分,但我希望我能对django-filter部分提供一些见解!

如果您使用DateRangeFilter,结果将是一个带有“任何日期”,“今天”,“过去7天”,“本月”和“今年”选项的下拉列表。

如果您的变量是“日期”,则其中任何一个都会为您提供带有“日期范围”标签的日期范围:

date_range = DateRangeFilter(name='date')
date = DateRangeFilter(label='Date_Range')

不同之处在于,如果您使用第一个,则可以再次使用变量“date”,这样您就可以选择按开始日期,结束日期或两者进行过滤(以获取日期之间),全部使用相同的日期变量。

(您只能在等号的左侧使用“日期”一次(或根本不使用))。

要获取开始日期和结束日期,请执行以下操作:

start_date = DateFilter(name='date',lookup_type=('lt'),) 
end_date = DateFilter(name='date',lookup_type=('gt'))

你不需要在Meta中再次调用“date”,但你可以。你需要打电话。它可能是您的日期,或者您想要过滤的其他字段。

以下是完整的代码和屏幕截图示例:

from django_filters import DateRangeFilter,DateFilter
from wesapp.models import MyModel

class SaleItemFilter(django_filters.FilterSet):
    start_date = DateFilter(name='date',lookup_type=('gt'),) 
    end_date = DateFilter(name='date',lookup_type=('lt'))
    date_range = DateRangeFilter(name='date')

    class Meta:
        model = SaleItem
        fields = ['entered_by',]

enter image description here

答案 1 :(得分:2)

你也可以试试DateFromToRangeFilter 这将使您能够这样做:

f = F({'date_0': '2016-01-01', 'date_1': '2016-02-01'})

其中F是具有FilterSet

date = DateFromToRangeFilter

http://django-filter.readthedocs.io/en/develop/ref/filters.html#datefromtorangefilter

答案 2 :(得分:0)

仅对当前django版本进行编辑,将name替换为field_name,将lookup_type替换为lookup_expr

下面给出了filters.py文件的示例

from django.contrib.auth.models import User
import django_filters

class UserFilter(django_filters.FilterSet):       
    username = django_filters.CharFilter(lookup_expr='icontains')
    first_name = django_filters.CharFilter(lookup_expr='icontains')
    last_name = django_filters.CharFilter(lookup_expr='icontains')
    year_joined = django_filters.NumberFilter(field_name='date_joined', lookup_expr='year',label='Year Joined')
    year_joined__gt = django_filters.NumberFilter(field_name='date_joined', lookup_expr='year__gt',label='Year Joined Greater Than')
    year_joined__lt = django_filters.NumberFilter(field_name='date_joined', lookup_expr='year__lt',label='Year Joined Less Than')
    date_range = django_filters.DateRangeFilter(field_name='date_joined')
    start_date = django_filters.DateFilter(field_name='date_joined',lookup_expr='lt',label='Date joined is before (mm/dd/yyyy):')
    end_date = django_filters.DateFilter(field_name='date_joined',lookup_expr='gt',label='Date joined is after (mm/dd/yyyy):')
    class Meta:
        model = User
        fields = ['username', 'first_name', 'last_name', ] 

答案 3 :(得分:0)

我知道这是旧帖子,但是要给出其他答案,您也可以通过以下方法启用和启用datepicker。使用django_filters的Datepicker。

import django_filters
from django_filters.widgets import RangeWidget

Date = django_filters.DateFromToRangeFilter(widget=RangeWidget(attrs={'type': 'date'}))