Django QuerySet Filter Exclude Null and Empty
Learn to Django QuerySet filter exclude null and empty strings in optional fields like alias. Chain exclude(alias__isnull=True).exclude(alias="") for non-null, non-empty values. Includes alternatives, best practices, and debugging tips.
Use a filter that excludes both NULL and empty strings:
# Only objects where alias is set (not NULL and not "")
Name.objects.filter(alias__isnull=False).exclude(alias="")
or equivalently:
Name.objects.exclude(alias__isnull=True).exclude(alias="")
Both queries return Name instances that have a non‑empty, non‑null alias.
To Django QuerySet filter exclude null and empty strings in an optional field like alias, chain exclude() calls: Name.objects.exclude(alias__isnull=True).exclude(alias=""). This pulls only records where alias has a real value—neither database NULL nor blank ''. You could flip it to filter(alias__isnull=False).exclude(alias=""), but the exclude chain feels more intuitive for most devs.
Contents
- Django QuerySet Filter Exclude Null and Empty Values
- Why Your Original Attempt Fails
- Correct Syntax for Django QuerySet Not Null Filter
- Alternatives: Django Filter by Field Not Empty
- Django ORM Exclude Empty Strings Best Practices
- Edge Cases in Django QuerySet Exclude Blank
- Common Mistakes and Debugging
- Sources
- Conclusion
Django QuerySet Filter Exclude Null and Empty Values
Picture this: you’ve got a Name model with an optional alias CharField. Some rows have alias=NULL (database null), others alias='' (empty string), and you want just the good stuff—actual values. Django filter empty values by tackling both at once.
The go-to fix? Chain excludes. Here’s the model for context:
from django.db import models
class Name(models.Model):
name = models.CharField(max_length=100)
alias = models.CharField(max_length=100, blank=True, null=True) # Optional, hence the mess
Raw data might look like:
alias=None(NULL)alias=''(empty)alias='DJ Shadow'(what you want)
Boom—queryset = Name.objects.exclude(alias__isnull=True).exclude(alias=""). Test it in the shell:
>>> from myapp.models import Name
>>> qs = Name.objects.exclude(alias__isnull=True).exclude(alias="")
>>> qs
<QuerySet [<Name: Real McCoy>, <Name: DJ Shadow>]>
>>> str(qs.query)
'SELECT ... WHERE NOT (alias IS NULL) AND NOT (alias = \'\')'
Why chain? A single filter() can’t negate two conditions easily without Q objects (more on that later). This approach shines for Django QuerySet exclude empty or null, hitting high search volumes because it’s the cleanest for most cases.
According to the Django querysets documentation, lookups like __isnull handle NULL perfectly, while __exact (or just =) nails strings.
Why Your Original Attempt Fails
Ever tried alias__neq=""? Yeah, it bombs. Django’s ORM skips __neq—no such lookup exists. You’ll get a FieldError: Unsupported lookup 'neq' for CharField.
Same deal with __ne="" in older Django (pre-2.0 it was finicky; now it’s __ne, but still doesn’t chain well for NULL+empty). Databases treat NULL differently: WHERE alias != '' skips NULLs automatically, but might snag whitespace-only strings.
Django filter out empty string from field needs precision. NULL isn’t equal to anything, even empty. A lone exclude(alias="") lets NULLs slip through. Chaining fixes it.
Quick demo of the fail:
# This misses NULLs!
Name.objects.exclude(alias="") # Returns empty strings? No, but NULLs yes.
# And this ignores empties but grabs NULLs? Wait, no—__isnull=False excludes NULL.
Name.objects.filter(alias__isnull=False) # Still has empties.
Stack Overflow discussions hammer this home: always chain for safety.
Correct Syntax for Django QuerySet Not Null Filter
Nail Django QuerySet not null filter with these battle-tested patterns. Pick based on readability.
Option 1: Double exclude (most popular)
Name.objects.exclude(alias__isnull=True).exclude(alias="")
- Pros: Dead simple, SQL-readable.
- Filters Django exclude null and empty string perfectly.
Option 2: Filter + exclude
Name.objects.filter(alias__isnull=False).exclude(alias="")
Equivalent SQL, but starts positive.
Option 3: Multi-arg exclude (Django 1.6+)
Name.objects.exclude(alias__isnull=True, alias="") # OR logic!
Wait—OR? Nope, that’s wrong for exclusion. Use for inclusion only. Stick to chaining for AND.
From Atlassian’s Django guide, here’s a cheat sheet:
| Goal | Query |
|---|---|
| Exclude NULL | exclude(alias__isnull=True) |
| Exclude empty | exclude(alias="") |
| Both | Chain above |
| Include both | filter(alias__isnull=True) | Q(alias="") |
Test counts:
# Assume 100 Names: 20 NULL, 30 empty, 50 real
len(Name.objects.all()) # 100
len(Name.objects.exclude(alias__isnull=True).exclude(alias="")) # 50
Alternatives: Django Filter by Field Not Empty
Django filter by field not empty? Beyond basics, level up.
Q Objects for complex logic (Django docs recommend):
from django.db.models import Q
# Exclude NULL OR empty (de Morgan's: NOT (NULL OR empty))
Name.objects.exclude(Q(alias__isnull=True) | Q(alias=""))
Expands to perfect SQL. Great for OR scenarios inverted.
String length trick:
Name.objects.filter(alias__isnull=False, alias__len__gt=0)
Skips whitespace? No—add .filter(alias__regex=r"^\s*(.+)\s*$") but overkill.
Django 2.0+ __ne:
Name.objects.filter(alias__isnull=False, alias__ne="")
But chaining excludes wins for most.
Studygyaan tutorial shows Q chaining excludes Django QuerySet exclude empty or null in loops.
For third-party: django-filter adds EmptyStringFilter—customize EMPTY_VALUES.
Django ORM Exclude Empty Strings Best Practices
Prevent the problem upstream. Django ORM exclude empty strings starts at the model.
Model tweaks:
class Name(models.Model):
alias = models.CharField(max_length=100, blank=False, null=False, default="")
null=False: No DB NULLs.blank=False: Form validation blocks empties.- But migration needed:
ALTER TABLE ... NOT NULL DEFAULT ''.
GeeksforGeeks warns: null=True on strings invites pain—PostgreSQL handles NULL better than MySQL.
Clean on save:
def save(self, *args, **kwargs):
if not self.alias or self.alias.strip() == "":
self.alias = None # Or raise ValidationError
super().save(*args, **kwargs)
For queries, annotate:
from django.db.models import Value, CharField
from django.db.models.functions import Length
Name.objects.annotate(
alias_len=Length('alias')
).filter(alias__isnull=False, alias_len__gt=0)
Edge Cases in Django QuerySet Exclude Blank
Django QuerySet exclude blank trips on…
JSONField/ArrayField: Can’t use ="". Try __gt="" or length:
from django.contrib.postgres.fields import ArrayField # Postgres only
Name.objects.filter(alias__len__gt=0) # For arrays
Whitespace: alias=" " slips through. Strip in query? Regex hell. Better: model clean.
Performance: On big tables, indexes matter. alias__isnull uses index; chains do too if ordered.
DB diffs: SQLite treats ‘’ as NULL sometimes—test.
Sentry.io notes bio fields (TextField) same rules.
django-filter tip: Override EMPTY_VALUES = [None, ''].
Common Mistakes and Debugging
Pitfalls:
filter(alias__ne=""): Misses NULL.- Forgetting
.distinct()on joins. null=True, blank=True: Future you hates it.
Debug:
qs = Name.objects.exclude(alias__isnull=True).exclude(alias="")
print(qs.query) # Raw SQL
print(list(qs.values('alias'))) # Values
from django.db import connection; print(connection.queries)
Hackersfriend lists multi-arg gotchas—chaining avoids.
What about alias__gte="a"? Hacks empties but locale-sensitive, no.
Sources
- How to filter empty or NULL names in a QuerySet? — Stack Overflow consensus on chaining exclude for NULL and empty strings: https://stackoverflow.com/questions/844556/how-to-filter-empty-or-null-names-in-a-queryset
- Queryset API — Official Django documentation on lookups like __isnull and exclude chaining: https://docs.djangoproject.com/en/stable/ref/models/querysets/
- How to Filter for Empty or NULL Values in a Django QuerySet — Atlassian guide with query tables and __ne examples: https://www.atlassian.com/data/databases/how-to-filter-for-empty-or-null-values-in-a-django-queryset
- How to Filter Empty or NULL Fields in Django Queryset — GeeksforGeeks on model best practices avoiding null=True: https://www.geeksforgeeks.org/python/how-to-filter-empty-or-null-fields-in-django-queryset/
- How to filter empty or NULL values in a QuerySet in Django — Studygyaan tutorial using Q objects for complex excludes: https://studygyaan.com/django/how-to-filter-empty-or-null-values-in-a-queryset-in-django
- django-filter Tips and Tricks — Documentation on custom empty value filters: https://django-filter.readthedocs.io/en/stable/guide/tips.html
- Filtering empty or NULL values in a Django QuerySet — Hackersfriend examples of multi-arg exclude pitfalls: https://www.hackersfriend.com/articles/filtering-empty-or-null-values-in-a-django-queryset
Conclusion
For Django QuerySet filter exclude null and empties, Name.objects.exclude(alias__isnull=True).exclude(alias="") is your reliable workhorse—simple, performant, and battle-tested. Pair it with model fixes like null=False to avoid headaches long-term. Fire up the shell, tweak for your data, and watch clean querysets roll in. Need Q objects for extras? You’ve got options. Questions on JSON edges? Hit the comments.