Django 쿼리 세트 필터링에서 동일하지 않은 방법은 무엇입니까?


664

장고 모델 검색어 세트, 나는 거기 것을 볼 __gt__lt비교급 값을하지만,이 __ne/ !=/ <>( 같지 않음 ?)

같지 않음을 사용하여 필터링하고 싶습니다.

예:

Model:
    bool a;
    int x;

내가 원하는

results = Model.objects.exclude(a=true, x!=5)

!=올바른 구문이 아닙니다. 나는 시도했다 __ne, <>.

나는 다음을 사용하여 끝났다.

results = Model.objects.exclude(a=true, x__lt=5).exclude(a=true, x__gt=5)

75
결과 = Model.objects.exclude (a = true) .filter (x = 5)가 작동 했습니까?
hughdbrown

3
@hughdbrown. 아니요. 검색어가 a=true먼저 제외 된 다음 x=5나머지에 필터 를 적용합니다 . 의도 된 쿼리와 만 요구 a=truex!=5. 차이는 모두 함께 해당되는 것으로 a=true하고는 x=5또한 필터링된다.
Mitchell van Zuylen

답변:


689

아마도 Q 객체 가이 문제에 도움이 될 수 있습니다. 나는 그것들을 사용한 적이 없지만 일반 파이썬 표현식처럼 부정하고 결합 할 수있는 것처럼 보입니다.

업데이트 : 방금 시도했지만 꽤 잘 작동하는 것 같습니다.

>>> from myapp.models import Entry
>>> from django.db.models import Q

>>> Entry.objects.filter(~Q(id = 3))

[<Entry: Entry object>, <Entry: Entry object>, <Entry: Entry object>, ...]

16
@ JCLeitão : 보다 직관적 인 구문은 아래 @ d4nt의 답변을 참조하십시오 .
Paul D. Waite

610

귀하의 쿼리에 이중 음수가있는 것처럼 보이므로 x가 5가 아닌 모든 행을 제외하고 싶습니다. 즉, x IS 5 인 모든 행을 포함하려고합니다. 이것은 트릭을 수행 할 것이라고 믿습니다.

results = Model.objects.filter(x=5).exclude(a=true)

특정 질문에 대답하기 위해 "같지 않음"은 없지만 django에 "filter"및 "exclude"메소드를 모두 사용할 수 있기 때문에 원하는 결과를 얻기 위해 항상 로직 라운드를 전환 할 수 있습니다.


2
@ d4nt : 제가 틀릴 수도 있지만 나는 쿼리가해야한다고 생각results = Model.objects.filter(a=true).exclude(x=5)
Taranjeet

1
@ Taranjeet : 원래 쿼리를 잘못 읽은 것 같습니다. OP가 x를 제외하고 (x = 5 제외) 부정하기를 원했기 때문에 d4nt의 버전이 올바르다 (a = True).

3
인스턴스 (x = 4, a = false)가 잘못 제외되기 때문에 이것이 잘못되었다고 생각합니다.
RemcoGerlich

4
@danigosa 그건 옳지 않은 것 같습니다. 방금 직접 시도했지만 순서 excludefilter호출은 의미있는 차이를 만들지 않았습니다. WHERE조항 의 조건 순서는 변경되지만 어떻게 중요합니까?
coredumperror

4
@danigosa 제외 및 필터 순서는 중요하지 않습니다.
EralpB

132

field=value쿼리 의 구문은 약칭입니다 field__exact=value. 즉, Django는 쿼리 연산자를 식별자의 쿼리 필드에 넣습니다 . Django는 다음 연산자를 지원합니다.

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

내가 같이 Q 객체와 이들을 결합하여 확신 데이브 보그 알 수 및 사용 filter()또는 exclude()제이슨 베이커는 제안 당신은 단지에 대한 가능한 모든 쿼리에 필요한 정확히 무엇을 얻을 수 있습니다.


고마워요 굉장합니다. 나는 이와 같은 것을 사용 tg=Tag.objects.filter(user=request.user).exclude(name__regex=r'^(public|url)$')했고 작동합니다.
suhailvs

@ suhail, 모든 데이터베이스가 정규 표현식 구문을 지원하는 것은 아닙니다 :)
Anoyz

2
난에서 icontains, iexact그리고 "대소 문자 구분을 무시"비슷한 의미합니다. "반전"이 아닙니다.
아이비는

exclude()여러 용어와 함께 사용하는 경우 OR예를 들어 exclude(Q(field1__queryop1=value1) | Q(field2__queryop2=value2))두 조건에서 결과를 제외하기 위해 운영자 와 함께 제안을 작성할 수 있습니다.
clapas

98

Django 1.7을 사용하여 사용자 지정 조회를 쉽게 만들 수 있습니다. Django 공식 문서 에는 __ne조회 예제가 있습니다 .

조회 자체를 먼저 작성해야합니다.

from django.db.models import Lookup

class NotEqual(Lookup):
    lookup_name = 'ne'

    def as_sql(self, qn, connection):
        lhs, lhs_params = self.process_lhs(qn, connection)
        rhs, rhs_params = self.process_rhs(qn, connection)
        params = lhs_params + rhs_params
        return '%s <> %s' % (lhs, rhs), params

그런 다음 등록해야합니다.

from django.db.models.fields import Field
Field.register_lookup(NotEqual)

이제 다음 __ne과 같이 쿼리 에서 조회를 사용할 수 있습니다 .

results = Model.objects.exclude(a=True, x__ne=5)

88

에서 장고 1.9 / 1.10 세 가지 옵션이 있습니다.

  1. 체인 excludefilter

    results = Model.objects.exclude(a=true).filter(x=5)
  2. 사용은 Q()오브젝트~연산자

    from django.db.models import Q
    object_list = QuerySet.filter(~Q(a=True), x=5)
  3. 맞춤 검색 기능 등록

    from django.db.models import Lookup
    from django.db.models.fields import Field
    
    @Field.register_lookup
    class NotEqual(Lookup):
        lookup_name = 'ne'
    
        def as_sql(self, compiler, connection):
            lhs, lhs_params = self.process_lhs(compiler, connection)
            rhs, rhs_params = self.process_rhs(compiler, connection)
            params = lhs_params + rhs_params
            return '%s <> %s' % (lhs, rhs), params

    register_lookup장식이 추가되었습니다 장고 1.8 및 사용자 정의 평소와 같이 조회 가능 :

    results = Model.objects.exclude(a=True, x__ne=5)

1
object_list = QuerySet.filter (~ Q (a = True), x = 5) : Q가 포함 된 후 Q를 포함하지 않는 다른 모든 조건을 유지해야합니다.
Bhumi Singhal

1
@MichaelHoffmann : A) ~ Q를 사용하여 제외 후 더 작은 데이터 세트를 필터링하므로 더 효율적입니다. B) 아마도 다른 방법으로 시퀀싱이 작동하지 않습니다 .. dun know .. dun 기억합니다!
Bhumi Singhal

41

모델과 함께, 당신이 필터링 할 수 있지만 =, __gt, __gte, __lt, __lte, 당신은 사용할 수 없습니다 ne, !=또는 <>. 그러나 Q 오브젝트를 사용하면 더 나은 필터링을 얻을 수 있습니다.

당신은 체인 피할 수 QuerySet.filter()QuerySet.exlude(),이를 사용 :

from django.db.models import Q
object_list = QuerySet.filter(~Q(field='not wanted'), field='wanted')

24

보류중인 디자인 결정. 한편, 사용exclude()

Django 이슈 트래커에는 "Queryset에"같지 않은 "필터 연산자가 없습니다" 라는 놀라운 항목 # 5763 이 있습니다 . 그것은 (2016 년 4 월 현재) "장고 석기 시대에 9 년 전", "4 년 전에 문을 닫음", "5 개월 전에 마지막으로 변경됨"으로 인해 주목할 만하다.

토론을 읽으면 흥미 롭습니다. 기본적으로 어떤 사람들 __ne은 추가해야 한다고 주장 하지만 다른 사람들 exclude()은 더 명확 하다고 말하면 추가 __ne 해서는 안됩니다 .

(나는 후자의 주장이 파이썬이 !=가지고 ==있고 not이미 가지고 있기 때문에 파이썬이 가지고 있지 않아야한다고 말하는 것과 거의 동일하기 때문에 전자에 동의합니다 ...)



18

당신은 이것을 사용 filter하고 exclude좋아 해야합니다

results = Model.objects.exclude(a=true).filter(x=5)

8

마지막 코드는 x! = 5이고 a가 True 인 모든 객체를 제외합니다. 이 시도:

results = Model.objects.filter(a=False, x=5)

위 행의 = 기호는 매개 변수 a에 False를 지정하고 매개 변수 x에 숫자 5를 지정한다는 것을 기억하십시오. 평등을 확인하지 않습니다. 따라서 쿼리 호출에서! = 기호를 사용하는 방법은 없습니다.


3
해당 필드에 Null 값이있을 수 있기 때문에 100 % 동일하지 않습니다.
MikeN

이것은 a = False x = 5 인 아이템들만 반환 하지만, 문제 (a = false, x = 4)가 포함됩니다.
RemcoGerlich

1
results = Model.objects.filter(a__in=[False,None],x=5)
Jeremy

8

결과 = Model.objects.filter (a = True) .exclude (x = 5)
이 SQL을 Generetes합니다.
a! = 0 및 x! = 5 인 tablex에서 *를 선택하십시오.
SQL은 True / False 필드가 표시되는 방식과 데이터베이스 엔진에 따라 다릅니다. 장고 코드 만 있으면됩니다.



6

당신이 찾고있는 무슨 중 하나가 모든 객체 a=false 또는 x=5 . Django |에서는 OR쿼리 세트 사이의 연산자로 사용됩니다 .

results = Model.objects.filter(a=false)|Model.objects.filter(x=5)

5

원하는 결과를 얻을 수 있습니다.

from django.db.models import Q
results = Model.objects.exclude(Q(a=True) & ~Q(x=5))

대한 같지 사용할 수있는 ~동일한 쿼리. 분명히 Q동일한 쿼리에 도달하는 데 사용할 수 있습니다.


편집 내용을 확인하십시오; 에 "and"를 사용 Q(a=True) and ~Q(x=5)하면 ~Q(x=5)에 대한 인수로 평가 됩니다 .exclude. docs.python.org/3/reference/expressions.html#boolean-operationsdocs.python.org/3/reference/…를 읽으 십시오 .
tzot

2

이 질문에 대한 많은 오답을 조심하십시오!

Gerard의 논리는 정확하지만 쿼리 세트가 아닌 목록을 반환하지만 중요하지는 않습니다.

쿼리 세트가 필요한 경우 Q를 사용하십시오.

from django.db.models import Q
results = Model.objects.filter(Q(a=false) | Q(x=5))
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.