19

デフォルトで使用可能な否定フィルターはありますか。アイデアは、djangoORMで次のことを実行できるということです。

model.objects.filter(field!=value)

それが可能であるならば、どうすればおいしいパイでそれをすることができますか?私は試した:

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

そして、それらのすべてが私にエラーを与えました。

4

5 に答える 5

28

残念ながらありません。

問題は、TastypieのModelResourceクラスがQuerySetのfilter()メソッドのみを使用することです。つまり、負のフィルターに使用する必要があるexclude()を使用しません。ただし、否定を意味するfilter()フィールドルックアップはありません。有効なルックアップは次のとおりです(このSO投稿の後):

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

私はそれをテストしていません。おそらくもっとエレガントな方法で書くこともできますが、うまくいくはずです:)

于 2012-03-16T21:13:42.950 に答える
6

コードを変更せずにこれを行う別の方法は、逆マッチングでiregexを使用することです

http://HOST/api/v1/resource/?format=json&thing__iregex=^((?!notThis).)*$
于 2013-09-25T23:32:30.963 に答える
2

私はこれのバグを開いて、ここで簡単な解決策を提供しました:https ://github.com/toastdriven/django-tastypie/issues/524

'!'を追加したほうがよいでしょう。質問で行ったように、フィールド名の最後にある文字..。

于 2012-06-13T14:04:32.060 に答える
1

Gorneauの上記の回答に関する注意:これは、MySQLバックエンドを使用していない場合にのみ機能するようです。見る:

#1139-正規表現から「繰り返し演算子オペランドが無効です」というエラーが発生しました

于 2015-02-14T02:50:55.007 に答える
-1

一部の値を回避するためにexclude()を使用します。例えば:

Person.filter(name="Tim").exclude(state="Down");
于 2016-02-15T14:26:58.563 に答える