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 5 months 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