4

I'm trying to use django_filter's DateFilter to filter by an exact date, but could not get it to return any result.

myapp/models.py

from django.db import models

class Event(models.Model):
    start = models.DateField()
    title = models.CharField(_'title'), max_length=256)

myapp/filters.py

from myapp.models import Event
import django_filters

class EventFilter(django_filters.FilterSet):
    start = django_filters.DateFilter(
        'start', label=_('With start date'),
        widget=forms.DateInput() # I'm using a datepicker-like widget to enter date
    )

    class Meta:
        model = Event 
        fields = ('start',)

For example: I have an event with start date 01/14/2012. When I entered that value in the date filter, it returns nothing.

I wasn't able to find a more in-depth description about DateFilter in django_filter's documentation site, either in its filter reference or Using django-filter guide. Or anywhere in general. Any ideas what I might be doing wrong?

I don't expect there's anything wrong with the date format from the datepicker widget since it's being used in another form (to enter data) and it works fine.

Additional info: I'm using django-1.6 and whatever the last version of django-filter

mathiass
  • 325
  • 1
  • 2
  • 10
  • 2
    Might not be related or just a typo pasting your code into SO but `fields = ('start')` is a string and should be `fields = ('start',)` – Scott Woodall Feb 13 '14 at 01:30
  • Thanks - that is my typo. It's `fields = ( 'start', )` in the code. – mathiass Feb 13 '14 at 03:24
  • Is the `'start'` in `... = django_filters.DateFilter('start', ...` necessary? – mathiass Feb 13 '14 at 03:51
  • Having `fields` defined will restrict what fields the filter can work with. In your example `title` is not available. – Scott Woodall Feb 13 '14 at 13:41
  • Does the name of the filter variable must match the model's field name? For example, if the model field name is `start`, can i use `start_date` as the filter variable? – mathiass Feb 13 '14 at 23:58
  • I'm answering my own questions re: the `'start'` in `django_filters.Datefilter('start', ...)` and naming of filter variable. In the former, `'start'` is the value for the `name` argument for the filter, referring to the field the filter should apply to. If that argument is not given (the latter), by default django_filter assumes the variable name as the field name. [source](https://django-filter.readthedocs.org/en/latest/ref/filters.html#name) – mathiass Feb 14 '14 at 00:08

2 Answers2

6

Found the issue.

The 'start' field is a DateTimeField. So when querying only for the date, no match is found because it never matches the time.

For example:

If I enter 01/14/2012, it looks for start date datetime.date(2012, 01, 14, 0, 0), but the actual start date may be datetime.datetime(2012, 01, 14, 21, 0, tzinfo=<UTC>).

Solution:

Use lookup_type='startswith' or 'lookup_type='contains' (source) but 'contains' appears to be faster

Class EventFilter(django_filters.FilterSet):
    start = django_filters.DateFilter(
        'start', label=_('With start date'),
        lookup_type='contains' # use contains
    )

    ...
Community
  • 1
  • 1
mathiass
  • 325
  • 1
  • 2
  • 10
4

You can filter datetime field by date

start = django_filters.DateFilter('start__date')
Jonhatan Fajardo
  • 348
  • 6
  • 11