我正在运行有关用户数据的指标,并希望排除那些包含“@ example.com”或“@ test.com”等虚假电子邮件的用户。
我试过
emails_to_exclude = ['@example.com', '@test.com', '@mailinator.com' ....]
Users.objects.exclude(email__endswith__in=emails_to_exclude)
不幸的是,这不起作用。看起来endswith
和in
看起来不太好。有什么想法吗?
答案 0 :(得分:12)
简单地遍历QuerySet,如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()
答案 1 :(得分:1)
您可以循环播放电子邮件并构建Q Object。实际上,如果你聪明的话,你可以做一个1班轮。
User.objects.exclude(bitwise_or_function[Q(email__endswith=e) for e in emails_to_exclude])
这样的事情。我不记得按顺序排列或整个列表的函数,我的Python生锈了。
答案 2 :(得分:0)
我更改了排除输入以使其成为set
并且没有“@”。否则,这应该做你想要的。
>>> 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']
答案 3 :(得分:0)
您也可以在单个查询中使用正则表达式执行此操作。
emails_to_exclude = ['@example.com', '@test.com', '@mailinator.com' ....]
User.objects.exclude(email__regex = "|".join(emails_to_exclude))
我不知道这个查询的效率。
这对SQLite不起作用,因为它没有内置的正则表达式支持。
答案 4 :(得分:0)
这应该适用于最新版本的Python和Django。 reduce
功能是一个好朋友。
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
) ) )
)
答案 5 :(得分:0)
实现这一目标的另一种方法:
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)