Пользовательская фильтрация и группировка в Django Rest Framework - PullRequest
0 голосов
/ 27 марта 2020

Я работаю над функциональностью, которая позволяет пользователям создавать пользовательские фильтры для определенных c моделей и сохранять эти результаты в виде группы. В качестве рабочего примера (для краткости импорт исключен):

class Client(models.Model):
    email = CIEmailField()

class Activity(models.Model):
    client = BaseForeignKey("client.Client", null=True, related_name="logged_activities")
    employee = BaseForeignKey("business.Employee", null=True, related_name="logged_activities")
    created = models.DateTimeField(auto_now_add=True)

Мы хотим создать фильтры, которые будут группировать Client s по Activity s на основе времени создания и связанных Employee и сохранять их результаты в группе, которая будет использоваться позже. Это довольно простая задача, за исключением того, что пользователю разрешено изменять конфигурацию фильтра и обновлять поля на Client, оба из которых могут измениться, независимо от того, соответствует ли Client критериям фильтра. (Примечание: в этом примере невозможно обновить Client, что может изменить набор результатов, но будущие фильтры будут.)

Мне бы хотелось, чтобы многие ко многим, чтобы мы могли легко получить группы клиент включен и, наоборот, включает клиентов в группу, но мне не совсем понятен лучший способ обработки конфигураций фильтров. В настоящее время это поддерживается в нашей системе, но фильтры не работают должным образом, и запросы фильтров выполняются всякий раз, когда необходимо использовать информацию о группе. Учитывая это, а также некоторые другие факторы, мы решили перестроить эту функциональность вместо попыток реорганизовать текущую реализацию.

1 Ответ

0 голосов
/ 27 марта 2020

Один грубый способ справиться с этим будет следующим. Вы создаете отображение или ловушку, ключ которой будет соответствовать полю промежуточной модели поля многие ко многим. Затем вы регистрируетесь (добавляете ключ / значение) для каждого из различных фильтров в отображении / ловушке. Вы создаете свои экземпляры промежуточной модели с соответствующими ключами. Затем, когда вам нужно использовать функциональные возможности конкретной группы, вы извлекаете экземпляр модели из базы данных и используете ключ, чтобы найти определенные функциональные возможности фильтра из сопоставления / ловушки.

config_groups = {}

class BaseConfig:
    key = None # Must be overridden by subclasses
    # I assume each of your filters has some common interface.
    # Put that here and raise NotImplemented exceptions for each function.

class AFilterConfig(BaseConfig):
    key = 'a_filter'
    # Implement AFilter's specific filtering logic.

config_groups[AFilterConfig.key] = AFilterConfig

class ConfigGroup(models.Model):
    # Relationship fields to Client and/or Activity
    key = models.CharField(max_length=16, unique=True, choices=list(config_groups.keys()))


def view_function(request):
    config_group = ConfigGroup.objects.get()
    filter_config = config_groups[config_group.key]

Если вы хотите сделайте еще один шаг, чтобы сделать это отображение / зацепку фактическим полем Django модели. Таким образом, вы сможете сделать следующее без необходимости импортировать и индексировать в отображение / ловушку.

def view_function(request):
    config_group = ConfigGroup.objects.get()
    filter_config = config_groups.filter_config
...