В конце я нашел исходный код внутри библиотеки и создал это решение:
class AliasesChoiceField(ChoiceField):
def valid_value(self, value):
for _, v in self.choices:
if value == v or str(value) == str(v):
return True
return False
class AliasesChoiceFilter(ChoiceFilter):
field_class = AliasesChoiceField
def filter(self, qs, value):
for val, alias in self.extra['choices']:
if value == alias:
return super(AliasesChoiceFilter, self).filter(qs, val)
return super(AliasesChoiceFilter, self).filter(qs, value)
На AliasesChoiceField.valid_value()
я просто скопировал базовый метод с простыми изменениями, чтобы правильно проверить значение.
AliasesChoiceFilter
используйте field_class
для проверки, поэтому я просто заменяю его на ChoiceFilter
и меняю filter()
метод на правильное сопоставление параметров моего выбора.
Наконец моя модель выглядит следующим образом
class ModelFilter(FilterSet):
STATUSES = (
(MyModel.STATUS_ACTIVE, 'active'),
(MyModel.STATUS_DONE, 'done')
)
status = AliasesChoiceFilter(choices=STATUSES)
И API-маршрут /app/model?status=active
работает правильно, устанавливая правильный статус при фильтрации.
Но! Это решение не будет работать для Django Admin или через веб-интерфейс API, поскольку оно будет предлагать реальные значения и будет пытаться передать 0
вместо active