How to filter empty or NULL names in a QuerySet?

DjangoDjango ModelsDjango QuerysetFilterNull

Django Problem Overview


I have first_name, last_name & alias (optional) which I need to search for. So, I need a query to give me all the names that have an alias set.

Only if I could do:

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

So, what is the equivalent to the above?

Django Solutions


Solution 1 - Django

You could do this:

Name.objects.exclude(alias__isnull=True)

If you need to exclude null values and empty strings, the preferred way to do so is to chain together the conditions like so:

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

Chaining these methods together basically checks each condition independently: in the above example, we exclude rows where alias is either null or an empty string, so you get all Name objects that have a not-null, not-empty alias field. The generated SQL would look something like:

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

You can also pass multiple arguments to a single call to exclude, which would ensure that only objects that meet every condition get excluded:

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

Here, rows in which some_field and other_field are true get excluded, so we get all rows where both fields are not true. The generated SQL code would look a little like this:

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

Alternatively, if your logic is more complex than that, you could use Django's Q objects:

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

For more info see this page and this page in the Django docs.

As an aside: My SQL examples are just an analogy--the actual generated SQL code will probably look different. You'll get a deeper understanding of how Django queries work by actually looking at the SQL they generate.

Solution 2 - Django

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

Solution 3 - Django

Firstly, the Django docs strongly recommend not using NULL values for string-based fields such as CharField or TextField. Read the documentation for the explanation:

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

Solution: You can also chain together methods on QuerySets, I think. Try this:

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

That should give you the set you're looking for.

Solution 4 - Django

1. When using exclude, keep the following in mind to avoid common mistakes:

Should not add multiple conditions into an exclude() block like filter(). To exclude multiple conditions, you should use multiple exclude().

Example: (NOT a AND NOT b)

Entry.objects.exclude(title='').exclude(headline='')

equal to

SELECT... WHERE NOT title = '' AND NOT headline = ''

======================================================

2. Only use multiple when you really know about it:

Example: NOT (a AND b)

Entry.objects.exclude(title='', headline='')

equal to

SELECT.. WHERE NOT (title = '' AND headline = '')

Solution 5 - Django

From Django 1.8,

from django.db.models.functions import Length

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

Solution 6 - Django

If you want to exclude null (None), empty string (""), as well as a string containing white spaces (" "), you can use the __regex along with __isnull filter option

Name.objects.filter(
    alias__isnull = False, 
    alias__regex = r"\S+"
)

alias__isnull=False excludes all the columns null columns

aliax__regex = r"\S+" makes sure that the column value contains at least one or more non whitespace characters.

Solution 7 - Django

You can simply do this:

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

It's really just that simple. filter is used to match and exclude is to match everything but what it specifies. This would evaluate into SQL as NOT alias='' AND alias IS NOT NULL.

Solution 8 - Django

this is another simple way to do it .

Name.objects.exclude(alias=None)

Solution 9 - Django

Another approach using a generic isempty lookup, that can be used with any field.

It can also be used by django rest_framework or other apps that use django lookups:

from distutils.util import strtobool
from django.db.models import Field
from django.db.models.lookups import BuiltinLookup

@Field.register_lookup
class IsEmpty(BuiltinLookup):
	lookup_name = 'isempty'
	prepare_rhs = False

	def as_sql(self, compiler, connection):
		sql, params = compiler.compile(self.lhs)
		condition = self.rhs if isinstance(self.rhs, bool) else bool(strtobool(self.rhs))
		if condition:
			return "%s IS NULL or %s = ''" % (sql, sql), params
		else:
			return "%s <> ''" % sql, params

You can then use it like this:

Name.objects.filter(alias__isempty=False)

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
Questionun33kView Question on Stackoverflow
Solution 1 - DjangoSasha ChedygovView Answer on Stackoverflow
Solution 2 - DjangojbofillView Answer on Stackoverflow
Solution 3 - Djangob3ng0View Answer on Stackoverflow
Solution 4 - DjangoHoangYellView Answer on Stackoverflow
Solution 5 - DjangoChemical ProgrammerView Answer on Stackoverflow
Solution 6 - DjangoAfsan Abdulali GujaratiView Answer on Stackoverflow
Solution 7 - DjangoTim TisdallView Answer on Stackoverflow
Solution 8 - DjangoImadOSView Answer on Stackoverflow
Solution 9 - Djangorptmat57View Answer on Stackoverflow