|
1 | 1 |
|
2 | | -from django.template import Template, TemplateDoesNotExist, loader |
3 | | -from rest_framework import compat |
| 2 | +from contextlib import contextmanager |
4 | 3 | from django_filters.rest_framework import backends |
5 | 4 |
|
6 | 5 | from .filterset import FilterSet |
|
9 | 8 | class DjangoFilterBackend(backends.DjangoFilterBackend): |
10 | 9 | default_filter_set = FilterSet |
11 | 10 |
|
12 | | - def filter_queryset(self, request, queryset, view): |
13 | | - filter_class = self.get_filter_class(view, queryset) |
14 | | - |
15 | | - if filter_class: |
16 | | - if hasattr(filter_class, 'get_subset'): |
17 | | - filter_class = filter_class.get_subset(request.query_params) |
18 | | - return filter_class(request.query_params, queryset=queryset).qs |
| 11 | + @contextmanager |
| 12 | + def patched_filter_class(self, request): |
| 13 | + """ |
| 14 | + Patch `get_filter_class()` to get the subset based on the request params |
| 15 | + """ |
| 16 | + original = self.get_filter_class |
19 | 17 |
|
20 | | - return queryset |
| 18 | + def get_subset_class(view, queryset=None): |
| 19 | + filter_class = original(view, queryset) |
21 | 20 |
|
22 | | - def to_html(self, request, queryset, view): |
23 | | - filter_class = self.get_filter_class(view, queryset) |
24 | | - if not filter_class: |
25 | | - return None |
26 | | - filter_instance = filter_class(request.query_params, queryset=queryset) |
| 21 | + if filter_class and hasattr(filter_class, 'get_subset'): |
| 22 | + filter_class = filter_class.get_subset(request.query_params) |
27 | 23 |
|
28 | | - # forces `form` evaluation before `qs` is called. This prevents an empty form from being cached. |
29 | | - filter_instance.form |
| 24 | + return filter_class |
30 | 25 |
|
31 | | - try: |
32 | | - template = loader.get_template(self.template) |
33 | | - except TemplateDoesNotExist: |
34 | | - template = Template(backends.template_default) |
| 26 | + self.get_filter_class = get_subset_class |
| 27 | + yield |
| 28 | + self.get_filter_class = original |
35 | 29 |
|
36 | | - return compat.template_render(template, context={ |
37 | | - 'filter': filter_instance |
38 | | - }) |
| 30 | + def filter_queryset(self, request, queryset, view): |
| 31 | + # patching the behavior of `get_filter_class()` in this method allows |
| 32 | + # us to avoid maintenance issues with code duplication. |
| 33 | + with self.patched_filter_class(request): |
| 34 | + return super(DjangoFilterBackend, self).filter_queryset(request, queryset, view) |
0 commit comments