Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Docs are incorrect about filtering by a Model[Multiple]ChoiceFilter #1661

Open
george-silva opened this issue May 20, 2024 · 4 comments
Open

Comments

@george-silva
Copy link

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.

@nils-van-zuijlen
Copy link

Thank you for your issue, I just bumped in the same issue, this also solved it for me.

@george-silva
Copy link
Author

Created a simple pull request fixing the example.

@medihack
Copy link

medihack commented Sep 1, 2024

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).

@gabn88
Copy link

gabn88 commented Nov 20, 2024

I also struggle with this.

IMO all "multiple" filters should allow all three syntaxes defined in #548. Now the __in requires comma-seperated values, whereas the ModelMultipleChoiceFilter requires the a=b&a=c syntax.

I tried to partly fix this with #1686, but that one seems to have gone stale.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

4 participants