-
Notifications
You must be signed in to change notification settings - Fork 127
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
neither contains or icontains is working #88
Comments
Hi @ericntd. There is both a list syntax and dict syntax for Also, make sure to use the |
does the icontains filter works for a related (ForeingKey) relationship? Wondering why it isnt working for me... |
icontains does not work on a foreign key value, although it will work across relationships on a foreign field. icontains isn't a registered lookup for FKs: |
I didn't get this part though:
You are saying that it will work if I'm querying the primary key of the foreign object? |
For example: class AuthorFilter(FilterSet):
class Meta:
model = Author
fields = {'username': ['icontains']}
class BookFilter(FilterSet):
author = RelatedFilter(AuthorFilter)
class Meta:
model = Book You could do |
Is there a way to do a symlink to a field of a class AuthorFilter(FilterSet):
class Meta:
model = Author
fields = {'username': ['icontains']}
class BookFilter(FilterSet):
username = RelatedFilter(AuthorFilter, name="username")
class Meta:
model = Book I just don't want the client to know that they are actually querying a related model, that is not relevant to them. |
I'm not sure if it will work, but you might be able to do... class BookFilter(FilterSet):
author = RelatedFilter(AuthorFilter, name="author__username") |
Ok, it didn't work... and I just realized that this solution does not work... You cannot traverse the author FK and do an icontains on a related field. |
You should be able to filter on related model fields. See this as an example - it's the same idea. The name aliasing - not so sure about that. I'll try to look into it further. |
I just get empty querysets if I don't put the exact value, for example: >> len(list(NoteFilter({"author__username__icontains": "u"}, queryset=Note.objects.all())))
0
>>len(list(NoteFilter({"author__username__icontains": "user1"}, queryset=Note.objects.all())))
2 This is my exact setting: settings.py REST_FRAMEWORK = {
'PAGE_SIZE': 10,
'DEFAULT_PAGINATION_CLASS':
'rest_framework.pagination.LimitOffsetPagination',
'DEFAULT_FILTER_BACKENDS': (
'rest_framework_filters.backends.DjangoFilterBackend',
'rest_framework.filters.SearchFilter',
),
} filters.py class ExtractionFilter(FilterSet):
"""Extraction Filter Class."""
#: ``analyte`` filter field.
analyte = AllLookupsFilter(name="analyte")
#: ``ext_id`` filter field.
ext_id = AllLookupsFilter(name="ext_id")
class Meta:
model = Extraction
class WorkflowFilter(FilterSet):
"""Workflow Filter Class."""
#: Nested filter for ``extraction`` ForeignKey relation.
extraction = RelatedFilter(ExtractionFilter, name="extraction")
class Meta:
model = Workflow >> len(list(WorkflowFilter({"extraction__analyte__icontains": "R"}, queryset=Workflow.objects.all())))
0
>> len(list(WorkflowFilter({"extraction__analyte__icontains": "RNA"}, queryset=Workflow.objects.all())))
100 |
Ok I think I found the problem... icontains does not work with fields that have choices ( class Extraction(Model):
analyte = models.CharField(
verbose_name=_("Biological Material"),
max_length=100,
choices=CHOICES,
null=True,
)
ext_id = models.CharField(
verbose_name=_("Extraction External ID"),
max_length=100,
blank=True,
default=None,
) Is this an expected behavior? |
Great catch! This if statement has been nagging me for a very long time but decided to just leave it be. The problem is that the value being filtered won't match any of the choices, so it won't validate and returns 0 results. I've submitted a PR (carltongibson/django-filter#447) to only create choice filters for exact lookups (which was probably the original intent anyway). The following should get around this: class FilterSet(filters.FilterSet):
@classmethod
def filter_for_lookup(cls, f, lookup_type):
# copy field and remove choices to bypass default behavior
# See: https://github.com/carltongibson/django-filter/issues/447
if f.choices and lookup_type != 'exact':
f = deepcopy(f)
f.choices = None
return super(FilterSet, cls).filter_for_lookup(f, lookup_type) |
@rpkilby hey! thank you very much, so I saw that django-filters merged your pull request. Thats great. I think I'll create a new "issue" for the field aliasing, I think that would be a nice feature for django-rest-framework-filters |
My
/api/articles/
returns 100 results.Both
/api/articles/title__contains=Hot
and/api/articles/title__icontains
return 100 results.Negation is working.
Exact match is working.
My ViewSet is as follows:
The text was updated successfully, but these errors were encountered: