Non model filters declared in class without label show "[invalid name]"
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:
Expected result would be something like this:
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.
In this case you should pass the label kwarg no? https://django-filter.readthedocs.io/en/stable/ref/filters.html#label
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.
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.