35👍
✅
Simply loop over the QuerySet, as QuerySets are lazy.
emails_to_exclude = ['@example.com', '@test.com', '@mailinator.com' ....]
users = Users.objects
for exclude_email in emails_to_exclude:
users = users.exclude(email__endswith=exclude_email)
users = users.all()
5👍
You can also do this with regular expressions in single query.
emails_to_exclude = ['@example.com', '@test.com', '@mailinator.com' ....]
User.objects.exclude(email__regex = "|".join(emails_to_exclude))
I don’t know the efficiency of this query.
This will not work for SQLite, as it has no built in regular expression support.
- How do I setup messaging and session middleware in a Django RequestFactory during unit testing
- How can I schedule a Task to execute at a specific time using celery?
2👍
One more way to achieve this:
from django.contrib.auth.models import User
from django.db.models import Q
emails_to_exclude = ['@example.com', '@test.com', '@mailinator.com']
users = User.objects.all()
filters = Q()
for ending in emails_to_exclude:
filters |= Q(email__endswith=ending)
filtered_users = users.filter(~filters)
- What is the right way to use angular2 http requests with Django CSRF protection?
- Override save_model on Django InlineModelAdmin
1👍
You can probably loop over the emails and build up a Q Object. Actually, you can probably do a 1-liner if you’re clever.
User.objects.exclude(bitwise_or_function[Q(email__endswith=e) for e in emails_to_exclude])
Something like that. I don’t remember the function to bitwise-OR a whole list together, my Python’s rusty.
👤mpen
- How do I simulate connection errors and request timeouts in python unit tests
- Combining multiple Django templates in a single request
- Django Can't Find My Templates
1👍
This should works with the latest version of Python and Django. The reduce
function is a good friend.
from functools import reduce
from operator import or_
from django.db.models import Q
emails_to_exclude = ['@example.com', '@test.com', '@mailinator.com' ....]
users = ( Users.objects
.exclude( reduce( or_, (
Q(( "email__endswith", k ))
for k in emails_to_exclude
) ) )
)
-1👍
I changed the exclusion input to make it a set
and to not have the “@”. Otherwise, this should do what you want.
>>> emails = ['foo@example.com', 'spam@stackoverflow.com', 'bad@test.com']
>>> excludes = {'example.com', 'test.com', 'mailinator.com'}
>>> [email for email in emails if email.split('@')[-1] not in excludes]
['spam@stackoverflow.com']
Source:stackexchange.com