4👍
I finally figured out the issue.
Apparently django-filters
does not handle correctly the lookup in
for foreign keys. The default filter for source__in
for instance, is ModelChoiceFilter
. So I had to explicitely define it as a ModelMultipleChoiceFilter
.
However I faced another issue which is that source__in=10&source__in=7
roughly translates into Q(source__in=10) | Q(source__in=7)
. Which is raises an exception as 10 and 7 are not iterables. So I changed my code to use the exact
lookup instead of in
but still use the ModelMultipleChoiceFilter
. Which, in the end, gives the following:
class BookingListFiltersForm(forms.Form):
state__in = forms.MultipleChoiceField(
choices=Booking.STATE_CHOICES, required=False,
label=_("État"), widget=forms.CheckboxSelectMultiple)
source = forms.ModelMultipleChoiceField(
queryset=Platform.objects.all(), required=False,
label=_("Source"), widget=ModelSelect2Multiple(
url='autocomplete:platform'))
class BookingManagerFilter(filters.FilterSet):
source = filters.ModelMultipleChoiceFilter(
queryset=Platform.objects.all())
payments__date = filters.DateFilter(method='payments__date_filter')
payments__method = filters.ChoiceFilter(
method='payments__method_filter',
choices=BookingPayment.METHOD_CHOICES,
)
class Meta:
model = Booking
fields = {
'period': [
'endswith', 'endswith__gte', 'endswith__lte',
'startswith', 'startswith__gte', 'startswith__lte',
],
'state': ['in'],
'source': ['exact'],
'booking_date': ['date', 'date__lte', 'date__gte'],
'accommodation': ['exact'],
'guest': ['exact']
}
def get_form_class(self):
return BookingListFiltersForm
7👍
I think documentation answers your question:
It’s not currently possible to filter by an empty string, since empty
values are interpreted as a skipped filter.GET http://localhost/api/my-model?myfield=
Further in the docs you have examples of possible solutions. Im putting here one of them
Solution 1: Magic values
You can override the filter() method of a filter class to specifically
check for magic values. This is similar to the ChoiceFilter’s null
value handling.
GET http://localhost/api/my-model?myfield=EMPTY
class MyCharFilter(filters.CharFilter): empty_value = 'EMPTY' def filter(self, qs, value): if value != self.empty_value: return super(MyCharFilter, self).filter(qs, value) qs = self.get_method(qs)(**{'%s__%s' % (self.name, self.lookup_expr): ""}) return qs.distinct() if self.distinct else qs
Right now i feel there is not enough information to solve your problem. I left a comment under your question. If you can provide that extra information it would greatly help understand what is going on.
For here are some tips that can help you track this bug:
- Install ipdb. it will help you execute code step by step and inspect each variables.
-
Drop breakpoint
import ipdb;ipdb.set_trace()
before lineFile "/home/tony/.venvs/cocoonr/lib/python3.6/site-packages/django/views/generic/list.py" in get 142. self.object_list = self.get_queryset()
I suspect you should find the culprit in https://github.com/carltongibson/django-filter/blob/82a47fb7bbddedf179f110723003f3b28682d7fe/django_filters/filterset.py#L215
You can do something like this
class BookingManagerFilter(filters.FilterSet):
# your previous code here
def filter_queryset(self, queryset):
import ipdb;ipdb.set_trace()
return super(BookingManagerFilter, self)filter_queryset(queryset):
And run your endpoint, ipdb will stop the app and you will be able to step into the code and inspect it.
- How do I run periodic tasks with celery beat?
- Upload direct to S3 or via EC2?
- How to fix Error: pg_config executable not found on Elastic Beanstalk permanently
- How to access POST data inside tastypie custom Authentication