Django filterset на агрегации, с несколькими выражениями поиска
Для API я вычисляю некоторые значения в реальном времени (простые агрегации/функции, такие как сумма, количество, отношение). Я хотел бы фильтровать эти значения с помощью различных операторов. В настоящее время для фильтров я использую класс filterset_class. Класс выглядит примерно так:
class BuildingFilter(filters.FilterSet):
class Meta:
model = Building
fields = {
"unit_number": ["gte", "gt", "lt", "lte", "range", "exact"],
}
address = filters.CharFilter(field_name="address", lookup_expr='icontains')
Модель Building имеет связь с моделью BuildingLeaseLog. В BuildingLeaseLog есть поле rent. В ответе API я возвращаю ключ "building_average_rent", который вычисляется с помощью аннотации в кверисете.
Итак, для поля building_average_rent (и других подобных) я хотел бы реализовать в этом классе фильтры со следующими операторами: "gte", "gt", "lt", "lte", "range", "exact". API может получить любую из комбинаций building_average_rent и операторов (например, building_average_rent__gte, building_average_rent__lt и т.д.), а класс filterset должен уметь фильтровать соответствующим образом
Однако, я не могу:
- include it directly in the fields list (like I did with unit_number), because it is not an actual field of the model
- call a filter like I did for address, because I need 7 filters for it (one for each operator), while for address, I am using only one operator (icontains). Maybe the lookup_expr could be passed dynamically, but I did not find a way to do so
- Include the calculated values directly to the Building model, for several reasons. Among them, it's because the values are calculated on different datasets depending on dynamic filters that are being applied. For ex, if a time-range is selected, the building_average_rent will be calculated on top of the subset of logs that include that time duration. Therefore, I am calculating in real time
Понятно, что есть другие способы, например, реализовать фильтр в queryset, с if-элементами для каждого оператора. Я пытаюсь найти способ сделать это в классе filterset, причем как можно более динамично
Есть советы/идеи о том, как этого достичь?