Django модель FilterSet - выбор базы данных и обновление полей фильтра из представления
У меня есть приложение Django, работающее с несколькими базами данных одинаковой структуры. Имя базы данных является частью url, поэтому оно приходит как аргумент в представление (self.kwargs['db']
). Я использую django-tables2
вместе с django-filter
для отображения данных таблицы (SingleTableMixin, FilterView
). Мне нужно установить, какая база данных должна использоваться для заполнения полей фильтра. В данный момент фильтр использует базу данных по умолчанию
filters.py
class FooFilter(django_filters.FilterSet):
class Meta:
model = Foo
fields = ['project', 'fooclass']
views.py
class FilteredFooView(SingleTableMixin, FilterView):
template_name = "metadata/metadata-filtered-table.html"
table_pagination = False
table_class = FooTable
model = Foo
filterset_class = FooFilter
def get_queryset(self):
return Foo.objects.using(self.kwargs['db']).all() # sets db for the table
def get_context_data(self, **kwargs):
context = super().get_context_data(**kwargs)
template_input = {'item': 'FooItem', 'name': getName(self.kwargs['db'])}
context = {**template_input, **context, **self.kwargs}
return context
Вы должны быть в состоянии передать имя db в kwargs, а затем использовать его во время init FilterSet
Здесь есть полезная информация; https://django-filter.readthedocs.io/en/stable/guide/usage.html#request-based-filtering
class FilteredFooView(SingleTableMixin, FilterView):
template_name = "metadata/metadata-filtered-table.html"
table_pagination = False
table_class = FooTable
model = Foo
filterset_class = FooFilter
# pass the db name to the FooFilter
def get_filterset_kwargs(self, filterset_class)
kwargs = super(FooFilter, self).get_filterset_kwargs(filterset_class)
kwargs['db'] = self.kwargs['db']
return kwargs
class FooFilter(django_filters.FilterSet):
def __init__(self, **kwargs):
# capture the db name
self.db_ = kwargs.pop['db']
super(FooFilter, self).__init__(**kwargs)
# override the base queryset
self.queryset = Foo.objects.using(db_).all()
class Meta:
model = Foo
fields = ['project', 'fooclass']