Подтвердить что ты не робот

Фильтр отклонений Tastypie

По умолчанию доступен фильтр отрицаний. Идея состоит в том, что вы можете сделать следующее в ORM django:

model.objects.filter(field!=value)

Как я могу сделать это в tastypie, если это возможно. Я пробовал:

someapi.com/resource/pk/?field__not=value
someapi.com/resource/pk/?field__!=value
someapi.com/resource/pk/?field!=value

И все они дали мне ошибки.

4b9b3361

Ответ 1

К сожалению, нет.

Проблема заключается в том, что класс Tastypie ModelResource использует только метод filter() для QuerySet, т.е. он не использует exclude(), который должен использоваться для отрицательных фильтров. Нет никакого поиска фильтра(), который будет означать отрицание. Действительные запросы (после SO post):

exact
iexact
contains
icontains
in
gt
gte
lt
lte
startswith
istartswith
endswith
iendswith
range
year
month
day
week_day
isnull
search
regex
iregex

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

Что-то вроде:

def apply_filters(self, request, applicable_filters):
    """
    An ORM-specific implementation of ``apply_filters``.

    The default simply applies the ``applicable_filters`` as ``**kwargs``,
    but should make it possible to do more advanced things.
    """
    positive_filters = {}
    negative_filters = {}
    for lookup in applicable_filters.keys():
        if lookup.endswith( '__not_eq' ):
            negative_filters[ lookup ] = applicable_filters[ lookup ]
        else:
            positive_filters[ lookup ] = applicable_filters[ lookup ]

    return self.get_object_list(request).filter(**positive_filters).exclude(**negative_filters)

вместо значения по умолчанию:

def apply_filters(self, request, applicable_filters):
    """
    An ORM-specific implementation of ``apply_filters``.

    The default simply applies the ``applicable_filters`` as ``**kwargs``,
    but should make it possible to do more advanced things.
    """
    return self.get_object_list(request).filter(**applicable_filters)

должен содержать следующий синтаксис:

someapi.com/resource/pk/?field__not_eq=value

Я не тестировал его. Вероятно, это может быть написано более элегантным способом, но вам нужно идти:)

Ответ 2

Другой способ сделать это без изменений кода - использовать iregex с обратным сопоставлением

http://HOST/api/v1/resource/?format=json&thing__iregex=^((?!notThis).)*$

Ответ 3

Я открыл для этого ошибку и предоставил здесь простое решение: https://github.com/toastdriven/django-tastypie/issues/524

Возможно, было бы лучше добавить '!' символ в конце имени поля, как вы это делали в своем вопросе...

Ответ 5

Я использую exclude(), чтобы избежать некоторых значений. Например:

Person.filter(name="Tim").exclude(state="Down");