dplex 0.3.2__tar.gz → 0.3.3__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {dplex-0.3.2 → dplex-0.3.3}/PKG-INFO +1 -1
- {dplex-0.3.2 → dplex-0.3.3}/dplex/internal/filter_applier.py +27 -19
- {dplex-0.3.2 → dplex-0.3.3}/dplex/internal/filters.py +21 -18
- {dplex-0.3.2 → dplex-0.3.3}/pyproject.toml +1 -1
- {dplex-0.3.2 → dplex-0.3.3}/LICENSE +0 -0
- {dplex-0.3.2 → dplex-0.3.3}/README.md +0 -0
- {dplex-0.3.2 → dplex-0.3.3}/dplex/__init__.py +0 -0
- {dplex-0.3.2 → dplex-0.3.3}/dplex/dp_filters.py +0 -0
- {dplex-0.3.2 → dplex-0.3.3}/dplex/dp_repo.py +0 -0
- {dplex-0.3.2 → dplex-0.3.3}/dplex/dp_service.py +0 -0
- {dplex-0.3.2 → dplex-0.3.3}/dplex/internal/query_builder.py +0 -0
- {dplex-0.3.2 → dplex-0.3.3}/dplex/internal/sort.py +0 -0
- {dplex-0.3.2 → dplex-0.3.3}/dplex/internal/types.py +0 -0
- {dplex-0.3.2 → dplex-0.3.3}/dplex/py.typed +0 -0
|
@@ -419,6 +419,9 @@ class FilterApplier:
|
|
|
419
419
|
self,
|
|
420
420
|
query_builder: SupportsFiltering,
|
|
421
421
|
filter_data: WordsFilter,
|
|
422
|
+
*,
|
|
423
|
+
model: type | None = None,
|
|
424
|
+
field_name: str | None = None,
|
|
422
425
|
) -> SupportsFiltering:
|
|
423
426
|
"""
|
|
424
427
|
Применить фильтр слов к нескольким колонкам
|
|
@@ -427,37 +430,41 @@ class FilterApplier:
|
|
|
427
430
|
Для каждого слова создается условие OR (слово должно быть найдено хотя бы в одной колонке).
|
|
428
431
|
Все слова объединяются через AND (все слова должны быть найдены).
|
|
429
432
|
|
|
430
|
-
Если filter_data.
|
|
433
|
+
Если filter_data.columns равен None, используются колонка текущего поля (model, field_name).
|
|
434
|
+
При отсутствии поля в модели выбрасывается ValueError.
|
|
435
|
+
|
|
436
|
+
Если filter_data.text пустой, фильтр не применяется.
|
|
431
437
|
|
|
432
438
|
Args:
|
|
433
439
|
query_builder: Query builder для применения фильтров
|
|
434
|
-
filter_data: Экземпляр WordsFilter
|
|
440
|
+
filter_data: Экземпляр WordsFilter
|
|
441
|
+
model: Модель для разрешения колонки по имени поля (при columns=None)
|
|
442
|
+
field_name: Имя поля для поиска (при columns=None)
|
|
435
443
|
|
|
436
444
|
Returns:
|
|
437
445
|
Query builder с примененным фильтром слов (или без изменений, если фильтр не активен)
|
|
438
446
|
|
|
439
|
-
|
|
440
|
-
|
|
441
|
-
>>> words_filter = WordsFilter("john developer", columns=[User.name, User.email])
|
|
442
|
-
>>> query = applier.apply_words_filter(query_builder, words_filter)
|
|
443
|
-
>>>
|
|
444
|
-
>>> # Фильтр не будет применен, если text или columns равны None
|
|
445
|
-
>>> inactive_filter = WordsFilter(None, None)
|
|
446
|
-
>>> query = applier.apply_words_filter(query_builder, inactive_filter) # вернет query без изменений
|
|
447
|
+
Raises:
|
|
448
|
+
ValueError: Если columns=None, field_name не задан или поле отсутствует в модели
|
|
447
449
|
"""
|
|
448
450
|
from sqlalchemy import and_, or_
|
|
449
451
|
|
|
450
|
-
search_columns = filter_data.columns
|
|
451
|
-
|
|
452
|
-
# Если columns равны None или пустые, фильтр не применяется
|
|
453
|
-
if search_columns is None or not search_columns:
|
|
454
|
-
return query_builder
|
|
455
|
-
|
|
456
452
|
words = filter_data.words
|
|
457
|
-
# Если
|
|
453
|
+
# Если text пустой — фильтр не применяется (не проверяем columns)
|
|
458
454
|
if not words:
|
|
459
455
|
return query_builder
|
|
460
456
|
|
|
457
|
+
search_columns = filter_data.columns
|
|
458
|
+
# Если columns заданы — используем их; иначе — колонку текущего поля
|
|
459
|
+
if search_columns is None or not search_columns:
|
|
460
|
+
if model is None or field_name is None:
|
|
461
|
+
return query_builder
|
|
462
|
+
if not hasattr(model, field_name):
|
|
463
|
+
raise ValueError(
|
|
464
|
+
f"WordsFilter: модель {model.__name__} не имеет поля '{field_name}'"
|
|
465
|
+
)
|
|
466
|
+
search_columns = [getattr(model, field_name)]
|
|
467
|
+
|
|
461
468
|
# Для каждого слова создаем условие: слово должно быть найдено хотя бы в одной колонке (OR)
|
|
462
469
|
word_conditions = []
|
|
463
470
|
for word in words:
|
|
@@ -516,8 +523,9 @@ class FilterApplier:
|
|
|
516
523
|
|
|
517
524
|
# Обрабатываем WordsFilter отдельно (может быть кастомным фильтром)
|
|
518
525
|
if isinstance(field_value, WordsFilter):
|
|
519
|
-
|
|
520
|
-
|
|
526
|
+
query_builder = self.apply_words_filter(
|
|
527
|
+
query_builder, field_value, model=model, field_name=field_name
|
|
528
|
+
)
|
|
521
529
|
continue
|
|
522
530
|
|
|
523
531
|
# Пропускаем поля, отсутствующие в модели
|
|
@@ -873,30 +873,30 @@ class WordsFilter:
|
|
|
873
873
|
Фильтр для поиска по нескольким словам с автоматической разбивкой строки
|
|
874
874
|
|
|
875
875
|
Автоматически разбивает строку на слова и предоставляет их для поиска.
|
|
876
|
-
|
|
877
|
-
в
|
|
876
|
+
Поддерживает два режима:
|
|
877
|
+
- columns задан: поиск в указанных колонках (для кастомных полей вроде query)
|
|
878
|
+
- columns=None: поиск в колонке текущего поля схемы (имя поля = имя колонки модели).
|
|
879
|
+
Если поле отсутствует в модели, при применении фильтра выбрасывается ValueError.
|
|
878
880
|
|
|
879
881
|
Args:
|
|
880
882
|
text: Строка для поиска, которая будет автоматически разбита на слова.
|
|
881
|
-
Если None
|
|
883
|
+
Если None или пустая, фильтр не применяется.
|
|
882
884
|
columns: Список колонок модели для поиска.
|
|
883
|
-
Если None,
|
|
885
|
+
Если None, используется колонка текущего поля (где WordsFilter в схеме).
|
|
884
886
|
|
|
885
887
|
Examples:
|
|
886
|
-
>>> #
|
|
887
|
-
>>>
|
|
888
|
-
|
|
888
|
+
>>> # Поиск по текущему полю (name в схеме -> User.name в модели)
|
|
889
|
+
>>> class UserFilters(DPFilters):
|
|
890
|
+
... name: WordsFilter | None = None
|
|
891
|
+
>>> filters = UserFilters(name=WordsFilter("john")) # поиск в User.name
|
|
889
892
|
>>>
|
|
890
|
-
>>> #
|
|
893
|
+
>>> # Поиск в нескольких колонках (кастомное поле query)
|
|
891
894
|
>>> class UserFilters(DPFilters):
|
|
892
895
|
... query: WordsFilter | None = None
|
|
896
|
+
>>> filters = UserFilters(query=WordsFilter("john dev", columns=[User.name, User.email, User.bio]))
|
|
893
897
|
>>>
|
|
894
|
-
>>>
|
|
895
|
-
>>>
|
|
896
|
-
>>> # Упрощенное использование: если text или columns равны None, фильтр не применяется
|
|
897
|
-
>>> filters = UserFilters(query=WordsFilter(None, None)) # фильтр не будет применен
|
|
898
|
-
>>> filters = UserFilters(query=WordsFilter("text", None)) # фильтр не будет применен
|
|
899
|
-
>>> filters = UserFilters(query=WordsFilter(None, [User.name])) # фильтр не будет применен
|
|
898
|
+
>>> # Не применяется при пустом text
|
|
899
|
+
>>> filters = UserFilters(name=WordsFilter(None)) # фильтр не будет применен
|
|
900
900
|
"""
|
|
901
901
|
|
|
902
902
|
def __init__(
|
|
@@ -907,9 +907,10 @@ class WordsFilter:
|
|
|
907
907
|
|
|
908
908
|
Args:
|
|
909
909
|
text: Строка для поиска, которая будет автоматически разбита на слова.
|
|
910
|
-
Если None, фильтр не
|
|
910
|
+
Если None, фильтр не применяется.
|
|
911
911
|
columns: Список колонок модели для поиска.
|
|
912
|
-
Если None,
|
|
912
|
+
Если None, используется колонка текущего поля (при применении).
|
|
913
|
+
Поле должно существовать в модели, иначе ValueError.
|
|
913
914
|
|
|
914
915
|
Returns:
|
|
915
916
|
None
|
|
@@ -953,8 +954,10 @@ class WordsFilter:
|
|
|
953
954
|
|
|
954
955
|
def __str__(self) -> str:
|
|
955
956
|
"""Человекочитаемое представление"""
|
|
956
|
-
if
|
|
957
|
+
if not self.text:
|
|
957
958
|
return "WordsFilter(inactive)"
|
|
958
959
|
if self.words:
|
|
959
|
-
|
|
960
|
+
if self.columns:
|
|
961
|
+
return f"WordsFilter({len(self.words)} words: {', '.join(self.words)} in {len(self.columns)} columns)"
|
|
962
|
+
return f"WordsFilter({len(self.words)} words: {', '.join(self.words)} in current field)"
|
|
960
963
|
return "WordsFilter(empty)"
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|