Tastypie Отрицательный Фильтр - PullRequest
18 голосов
/ 13 марта 2012

Есть ли фильтр отрицания, доступный по умолчанию.Идея состоит в том, что вы можете сделать следующее в 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

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

Ответы [ 5 ]

27 голосов
/ 17 марта 2012

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

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

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» от остальных. Затем вы должны передать первую группу в exclude (), а остальные в filter ().

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

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

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

6 голосов
/ 26 сентября 2013

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

http://HOST/api/v1/resource/?format=json&thing__iregex=^((?!notThis).)*$
2 голосов
/ 13 июня 2012

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

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

1 голос
/ 14 февраля 2015

Примечание к приведенному выше ответу Горно: похоже, это работает, только если вы не используете бэкэнд MySQL. См:

# 1139 - Получено сообщение об ошибке «Операнд оператора повторения недействителен» из регулярного выражения

0 голосов
/ 15 февраля 2016

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

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