У меня есть для DRF странички фильтрация (кастомная):
/cars/filters.py:
class EngineFilter(filters.FilterSet):
"""Custom filtering for Engine model list."""
tank_choices = (
("gas", "Gasoline"),
("diesel", "Diesel"),
("hybrid", "Hybrid"),
("electro", "Electro"),
("etc", "Etc."),
)
engine_brands_list = []
for val in Engine.objects.values_list('engine_brand'):
if (val[0], val[0]) not in engine_brands_list:
engine_brands_list.append((val[0], val[0]))
fuel_type = filters.ChoiceFilter(choices=tank_choices)
engine_brand = filters.ChoiceFilter(choices=engine_brands_list)
hp = filters.RangeFilter()
engine_volume = filters.RangeFilter()
is_active = filters.BooleanFilter()
class Meta:
model = Engine
fields = ['fuel_type', 'engine_brand', 'hp', 'engine_volume', 'is_active']
Здесь есть два ChoiceField-s, один - для статичных значений (fuel_type), другой для брендов, т.к. бренды надо сортировать только по тем, которые есть в БД. Проблема в том, что когда я в DRF добавляю какую-то новую запись с новым брендом, то уже сформированный фильтр не добавляется и, к примеру, вот такой тест вернет мне ошибку
{'engine_brand': [ErrorDetail(string='Select a valid choice. Some-Brand is not one of the available choices.', code='invalid_choice')]}:
@pytest.mark.django_db
def test_engine_brand_filter(engine):
"""
Testing if the engine_brand field filter will provide
correct data filtration for engines list page.
"""
response = c.get("/api/cars/engines/?engine_brand=Some-Brand")
print(response.data)
serializer_data = EngineSerializer(engine[1]).data
assert response.status_code == status.HTTP_200_OK, "Should be 200"
assert response.data[0] == serializer_data, "Should be equal"
Ошибка формируется как раз из-за того, что запись я добавил, в бд она сохранилась, но custom filter уже был сформирован, уже выгрузил в ChoiceField доступные на момент запуска choices и о других не знает. Может быть есть возможность сделать так, чтобы при добавлении новой записи в бд кастомный фильтр "пересобирался" и получал уже обновленный список брендов?