Docs are incorrect about filtering by a Model[Multiple]ChoiceFilter
george-silva opened this issue · 4 comments
In the current documentation we have this following example:
class FooFilter(BaseFilterSet):
foo = django_filters.filters.ModelMultipleChoiceFilter(
field_name='attr__uuid',
to_field_name='uuid',
queryset=Foo.objects.all(),
)
However, it's not necessary to set the filter field_name
to point to the uuid
field. The only needed step is to add the to_field_name
and point to the correct relationship.
In my case I've tried doing what is described above, but this fails here:
location: django_filters.filters.ChoiceFilter#158
class ChoiceFilter(Filter):
field_class = ChoiceField
def __init__(self, *args, **kwargs):
self.null_value = kwargs.get('null_value', settings.NULL_CHOICE_VALUE)
super().__init__(*args, **kwargs)
def filter(self, qs, value):
if value != self.null_value:
return super().filter(qs, value)
qs = self.get_method(qs)(**{'%s__%s' % (self.field_name, self.lookup_expr): None})
return qs.distinct() if self.distinct else qs
The reason it fails is that value
in this particular code location is already the related model. If you use related_model__uuid
as the field name, the lookup becomes: related_model__uuid
and value is the model itself. Django fails when it tries to convert the related model instance to an UUID.
The only necessary change seems to be changing the field_name
to remove the extra __uuid
.
Thank you for your issue, I just bumped in the same issue, this also solved it for me.
Created a simple pull request fixing the example.
That is strange. I stumbled across this issue by chance, but I have to add the suffix to the field_name
:
This works in my case:
modalities = django_filters.ModelMultipleChoiceFilter(
queryset=Modality.objects.order_by("code"),
field_name="modalities__code",
to_field_name="code",
)
But this doesn't:
modalities = django_filters.ModelMultipleChoiceFilter(
queryset=Modality.objects.order_by("code"),
field_name="modalities",
to_field_name="code",
)
(Error: Field 'id' expected a number but got 'CT'.
, where CT is a unique code).