django-filter icon indicating copy to clipboard operation
django-filter copied to clipboard

Non model filters declared in class without label show "[invalid name]"

Open hyperstown opened this issue 1 year ago • 2 comments

Hello I noticed that declaring non model field filter without label in filterset class is not displayed properly in filter form.

So for this example model:

class Post(models.Model):
    title =  models.CharField(max_length=250)
    description = models.TextField()
    author = models.ForeignKey(User, on_delete=models.CASCADE, related_name='posts')


class Comment(models.Model):
    text = models.TextField()
    post = models.ForeignKey(Post, on_delete=models.CASCADE, related_name='comments')
    author = models.ForeignKey(User, on_delete=models.CASCADE, related_name='comments')

and this viewset:

class PostViewSet(viewsets.ModelViewSet):

    queryset = Post.objects.annotate(has_comments=Exists(Comment.objects.filter(post_id=OuterRef('pk'))))
    serializer_class = PostSerializer
    filterset_class = PostFilterSet

and this filterset:

class PostFilterSet(filters.FilterSet):

    has_comments = filters.BooleanFilter()

    class Meta:
        model = Post
        fields = '__all__'

Filters in form will look like this:

image

Expected result would be something like this:

image

I know that this can be accomplished adding label parameter to BooleanFilter but it's very inconvenient. Form should not show [invalid name] unless it absolutely cannot figure out field name.

As a potential solution I propose changing verbose_field_name function in django_filters/utils.py.

From:

parts = get_field_parts(model, field_name)
if not parts:
    return "[invalid name]"

to:

parts = get_field_parts(model, field_name)
if not parts:
    return field_name.replace("_", " ")

I can make a PR but before that I want to make sure that it's not just some kind of mistake on my part.

hyperstown avatar Sep 03 '24 18:09 hyperstown

In this case you should pass the label kwarg no? https://django-filter.readthedocs.io/en/stable/ref/filters.html#label

carltongibson avatar Sep 04 '24 07:09 carltongibson

But that's the thing, why should I specify label each time when field name is not unknown? We have access to field name in that function but we still choose to return [Invalid Name].
I think that label role is for example more in case of field abbreviations. So for example filed name is p_txt and label should be Private text. Or just in general when you want to name field differently but you want to keep filter name. But if field name is first_name there is no reason for me to get out of my way to specify label First name. It's redundant and inconvenient in my opinion.

hyperstown avatar Sep 04 '24 11:09 hyperstown

why should I specify label each time

Introspection and auto-generation of model filter is a core part of django-filter. Non-model filters you define explicitly. Always have, always will.

Beyond a change here being an unnecessary backwards incompatibility break, there are too many We could do this… options once you start trying to guess how folks want their filters generated. That leads to a world of difficult bug reports and maintenance. In contrast, you can just pass the label kwarg in your code. Much cleaner. Not ambiguous.

I hope that makes sense.

carltongibson avatar Mar 11 '25 10:03 carltongibson