A RetroSearch Logo

Home - News ( United States | United Kingdom | Italy | Germany ) - Football scores

Search Query:

Showing content from https://github.com/carltongibson/django-filter/issues/446 below:

Any interested in nullable/is-not-set fields? · Issue #446 · carltongibson/django-filter · GitHub

Hi there,

Incredible library and super easy to use. Very Djangonic/Pythonic.

One use case I have is filtering by date or date not being set. Now, this can easily be done with the meta syntax:

    class Meta:
        model = models.Widget
        fields = {
            'approved_at': ['exact', 'gte', 'lte', 'isnull'],
        }

But that technically creates three filters. For doing that with one filter, you can currently use DateFromToRangeFilter, but you lose the "is not set" functionality. I find using one filter to be more idiomatic, specially if you are generating a UI from it and want just one widget.

So I wrote this crude first pass:

class NullableRangeWidget(django_filters.widgets.RangeWidget):
    def __init__(self, attrs=None):
        widgets = (forms.TextInput, forms.TextInput, forms.NullBooleanSelect)
        forms.MultiWidget.__init__(self, widgets, attrs)


class NullableDateRangeField(django_filters.fields.RangeField):
    widget = NullableRangeWidget

    def __init__(self, *args, **kwargs):
        fields = (
            forms.DateField(),
            forms.DateField(),
            forms.BooleanField())
        super(NullableDateRangeField, self).__init__(fields, *args, **kwargs)

    def compress(self, data_list):
        if data_list:
            start_date, stop_date, is_null = data_list

            if is_null:
                return 'MAGIC'
            else:
                return super(NullableDateRangeField, self).compress([start_date, stop_date])
        return None


class NullableDateRangeFilter(django_filters.filters.RangeFilter):
    field_class = NullableDateRangeField

    def filter(self, qs, value):
        if value == 'MAGIC':
            lookup = '%s__isnull' % self.name
            return self.get_method(qs)(**{lookup: True})
        return super(NullableDateRangeFilter, self).filter(qs, value)

Any interest in something like this? So now you can say "approved_at" is not set.

Let me know and I'd be happy to clean it up and make a PR. I'd also need some suggestions on how to use a magic value to trigger the null check (as None is not usable).

Best,

Silvio


RetroSearch is an open source project built by @garambo | Open a GitHub Issue

Search and Browse the WWW like it's 1997 | Search results from DuckDuckGo

HTML: 3.2 | Encoding: UTF-8 | Version: 0.7.4