쿼리 세트에서 빈 이름 또는 NULL 이름 필터링


463

내가 가진 first_name, last_name& alias내가 검색해야합니다 (옵션). 따라서 별칭이 설정된 모든 이름을 제공하는 쿼리가 필요합니다.

내가 할 수있는 경우에만 :

Name.objects.filter(alias!="")

따라서 위와 동등한 것은 무엇입니까?

답변:


839

당신은 이것을 할 수 있습니다 :

Name.objects.exclude(alias__isnull=True)

null 값 빈 문자열 을 제외해야하는 경우 선호하는 방법은 다음과 같이 조건을 연결하는 것입니다.

Name.objects.exclude(alias__isnull=True).exclude(alias__exact='')

이러한 메소드를 함께 연결하면 기본적으로 각 조건을 독립적으로 확인합니다. 위의 예제에서 aliasnull 또는 비어있는 문자열 인 행을 제외 하므로 null이 아니거나 비어 Name있지 않은 alias필드 가있는 모든 객체를 가져옵니다 . 생성 된 SQL은 다음과 같습니다.

SELECT * FROM Name WHERE alias IS NOT NULL AND alias != ""

에 대한 단일 호출에 여러 인수를 전달하여 모든 조건 exclude을 충족하는 객체 만 제외 되도록 할 수 있습니다 .

Name.objects.exclude(some_field=True, other_field=True)

여기서, 행이있는 some_field 그리고 other_field 우리는 두 필드가 사실이 아닌 모든 행을 얻을 수 있도록 진정한 GET은 제외됩니다. 생성 된 SQL 코드는 다음과 같습니다.

SELECT * FROM Name WHERE NOT (some_field = TRUE AND other_field = TRUE)

또는 논리가 그보다 복잡한 경우 장고의 Q 객체를 사용할 수 있습니다 .

from django.db.models import Q
Name.objects.exclude(Q(alias__isnull=True) | Q(alias__exact=''))

더 많은 정보를 참조 페이지이 페이지 장고 문서에 있습니다.

제쳐두고 : 내 SQL 예제는 단지 비유입니다. 실제로 생성 된 SQL 코드는 아마도 다르게 보일 것입니다. Django 쿼리가 실제로 생성하는 SQL을 살펴보면 Django 쿼리의 작동 방식에 대해 더 깊이 이해할 수 있습니다.


5
편집 내용이 잘못되었다고 생각합니다. 연쇄 필터는 SQL을 자동으로 만들지 않으며 OR(이 경우에만) SQL을 생성합니다 AND. 참조 할 수 있도록이 페이지를 참조하십시오 : docs.djangoproject.com/en/dev/topics/db/queries/... 체인의 장점은 당신이 혼합 수 있다는 것입니다 excludefilter복잡한 쿼리 조건을 모델링 할 수 있습니다. 실제 SQL을 모델링 OR하려면 Django Q 오브젝트를 사용해야합니다. docs.djangoproject.com/en/dev/topics/db/queries/… 응답이 심각하게 오도되기 때문에이를 반영하도록 편집을 편집하십시오. .
shezi

1
@ shezi : 나는 그것을 더 유추로 의미했습니다. 실제 SQL 코드가 OR조건을 융합 하기 위해를 사용한다고 보장되는 것은 아닙니다 . 명확하게 답변을 편집하겠습니다.
Sasha Chedygov

1
이 논리를 나타내는 여러 가지 방법이 있습니다 (예 NOT (A AND B):와 동일 함) NOT A OR NOT B. SQL을 알고 있지만 ORM에 익숙하지 않은 새로운 Django 개발자에게는 혼동을 줄 수 있습니다.
Sasha Chedygov

3
나는 De Morgan의 법칙을 알고 있으며 이것이 바로 요점입니다. 귀하의 예제 AND는 첫 번째 쿼리에서를 OR사용 중이기 때문에 이점을 갖기 때문에 작동합니다 exclude. 일반적으로 체인을 THEN, 즉 으로 생각하는 것이 더 정확할 것입니다 exclude(A) THEN exclude(B). 위의 가혹한 언어에 대해 죄송합니다. 귀하의 답변은 실제로 좋지만 새로운 개발자가 귀하의 답변을 너무 일반적으로 받아들이는 것이 걱정됩니다.
shezi

2
@ shezi : 충분히 공정합니다. 내가 장고의 관점에서가 아니라 SQL의 관점에서 생각하는 것이 좋습니다 동의, 난 그냥 제시의 측면에서 연쇄 생각 ANDOR는 SQL 배경에서 장고에 오는 사람에게 유용 할 수 있습니다. 장고에 대한 더 깊은 이해를 위해 문서는 내가 할 수있는 것보다 더 나은 일을한다고 생각합니다.
Sasha Chedygov

49
Name.objects.filter(alias__gt='',alias__isnull=False)

2
확실하지 않지만 alias__isnull=False조건이 중복 적이라고 생각합니다 . 필드가 Null반드시 첫 번째 절에서 제외됩니까?
Bobble

이전의 의견 / 질문 외에도 다른 긍정적 인 답변보다 여기에 긍정적 인 논리가 따르기 쉽다고 생각합니다.
Bobble

데이터베이스 구현에 의존하는 @Bobble- 순서는 데이터베이스에 위임 됨
wpercy

alias__gtJSON과 같은 빈 문자열을 제외하려는 JSON 유형 열에서 작동하는 유일한 방법이었습니다 {'something:''}. 따라서 작동 구문은 다음과 같습니다.jsoncolumnname__something__gt=''
bartgras

38

첫째, Django 문서는 CharField 또는 TextField와 같은 문자열 기반 필드에 NULL 값을 사용하지 않는 것이 좋습니다. 설명을 보려면 설명서를 읽으십시오.

https://docs.djangoproject.com/en/dev/ref/models/fields/#null

솔루션 : QuerySet에서 메소드를 함께 연결할 수도 있습니다. 이 시도:

Name.objects.exclude(alias__isnull=True).exclude(alias="")

원하는 세트를 제공해야합니다.


5

장고 1.8에서

from django.db.models.functions import Length

Name.objects.annotate(alias_length=Length('alias')).filter(alias_length__gt=0)

5
이것은 "당신이 뭔가처럼 보인다 수 있습니다 할"당신이하지 뭔가 해야 하지. 두 가지 간단한 검사에 비해 쿼리 복잡성이 크게 증가합니다.
Oli

3

를 사용할 때 일반적인 실수를 피하려면 다음을 exclude기억하십시오.

와 같이 exclude () 블록 에 여러 조건을 추가 없습니다 . 여러 조건을 제외하려면 여러 개의 exclude ()를 사용해야합니다filter

잘못된 :

User.objects.filter (email='example@example.com '). exclude (profile__nick_name =' ', profile__avt =' ')

맞음 :

User.objects.filter (email='example@example.com '). exclude (profile__nick_name =' '). exclude (profile__avt =' ')


0

당신은 단순히 이것을 할 수 있습니다 :

Name.objects.exclude(alias="").exclude(alias=None)

정말 간단합니다. filter일치하는 데 사용되며 exclude지정된 것을 제외한 모든 것을 일치시키는 것입니다. 이것은 SQL로 평가됩니다 NOT alias='' AND alias IS NOT NULL.


이것은 올바르지 않습니다. 이 질문은 쿼리에서 빈 ( alias="") 및 NULL ( alias=None) 별칭 을 제외하는 것을 목표로 합니다. 귀하의 인스턴스는로 포함됩니다 Name(alias=None).
damon

@damon- .filter(alias!="")제목과 같지 않은 내용에 대답했습니다 . 내 답변을 편집했습니다. 그러나 문자 필드는 NULL 값을 허용하지 않으며 규칙에 따라 값이 아닌 경우 빈 문자열을 사용해야합니다.
Tim Tisdall

-1

이것은 또 다른 간단한 방법입니다.

Name.objects.exclude(alias=None)

None와 같은 것이 아닙니다 "".
Tim Tisdall
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.