[resolved] typo in application code
mosesmc52 opened this issue · 19 comments
Th django-rest-framework-filters is not not working with my install of Django v.2.2.4. I have djangorestframework-filters v 1.0.0.dev0 installed, python v. 3.7.4 . I believe I have everything installed as described in the instructions. I'm not sure this makes a difference, within the view I'm using the filter_class within generics.ListAPIView. What steps can I take to troubleshoot this issue?
I'm testing using the Django Rest Framework UI.
Thanks,
Moses
Hi @mosesmc52. There isn't enough information to debug this. What do you mean by "not working"? Do you get an exception, or does nothing seem to happen?
Are you using the correct backend?
'rest_framework_filters.backends.RestFrameworkFilterBackend'
Yes, I'm using the correct backend.
Here is the sample of my filter:
class ApplicationFilter(filters.FilterSet):
class Meta:
models = models.Application
fields = {
'title': '__all__',
}
class ApplicationList(generics.ListAPIView):
queryset = dealer_models.Application.objects.all()
serializer_class = dealer_serializers.ApplicationSeializer
filter_class = application_filters.ApplicationFilter
What exactly isn't working? Do you get an exception, or are the query results not filtered? All I can give you is generic debugging advice.
- What is the querystring that isn't working? It's possible that it's just invalid.
- Log the database queries. Does the application query have a where clause for the title field?
- If you're familiar with a debugger, then use that to walk though the code as it's executed.
- If not, you can use simple print statements to help figure out what's going on. e.g.,
class ApplicationFilter(filters.FilterSet):
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
print('*' * 80)
print('ApplicationFilter init')
class Meta:
models = models.Application
fields = {'title': '__all__'}
If you don't see ApplicationFilter init
in your dev server logs, then that would indicate that your application filter isn't being ran.
I copied the init method into my Application filter with the print statments. I used the pdb debugger and saw the input kwargs params being passed within the title field. I don't think the filter is working. I inserted a random string expecting nothing to be returned. However, I saw a few application objects being returned. I'm going to try to figure out to log the database query. Unless you know of any other ways I can troubleshoot.
Thanks for your help
What is the querystring you are using?
Here is my query running on localhost.
Okay - so there shouldn't be any issue with the query params, and you saw that they were passed to the filterset, so that's encouraging. Next step would be to see what SQL queries are being executed. Try this:
import sqlparse
def print_sql(qs):
query = str(qs.query)
print(sqlparse.format(query, reindent=True, keyword_case='upper'))
class ApplicationFilter(filters.FilterSet):
class Meta:
models = models.Application
fields = {'title': '__all__'}
def filter_queryset(self, queryset):
queryset = super().filter_queryset(queryset)
print_sql(queryset)
return queryset
You might also want to take a look at https://stackoverflow.com/q/4375784/1103124
Can you show the full query? There should be more after from the FROM
line.
Okay, so your filter is called, it's passed data etc, but no query is produced.. try:
class ApplicationFilter(filters.FilterSet):
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
print('*' * 80)
print('Data:')
for k, v in self.data.items():
print(f'{k}: {v}')
print('Base filters:')
for name, f in self.base_filters.items():
print(f'{name}: {type(f)}')
print('Request filters:')
for name, f in self.filters.items():
print(f'{name}: {type(f)}')
ah - meant to inspect the base_filters
on the class, not the instance. Try this instead:
class ApplicationFilter(filters.FilterSet):
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
print('*' * 80)
print('Base filters:')
for name, f in type(self).base_filters.items():
print(f'{name}: {type(f)}')
hm - that doesn't make sense. Your filterset class should have an unmodified set of base_filters
. What happens if you just import the class in the shell and print the filters?
import ApplicationFilter
print(ApplicationFilter.base_filters)
Oh wow - just figured it out. There's a typo in the filterset.
class ApplicationFilter(filters.FilterSet):
class Meta:
# this is incorrect
models = models.Application
# should be...
model = models.Application
fields = {
'title': '__all__',
}
Fix that and Meta.fields
should generate your title
filters.
It worked!!!
Thank you again.