Django 查询集:使用endswith 排除电子邮件列表

问题描述 投票:0回答:7

我正在对用户数据运行指标,并希望排除拥有“@example.com”或“@test.com”等虚假电子邮件的用户。

我试过了

emails_to_exclude = ['@example.com', '@test.com', '@mailinator.com' ....]
Users.objects.exclude(email__endswith__in=emails_to_exclude)

不幸的是,这不起作用。看起来

endswith
in
相处得不太好。有什么想法吗?

django django-queryset
7个回答
35
投票

只需循环查询集,因为查询集是惰性的

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
投票

您还可以在单个查询中使用正则表达式来执行此操作。

emails_to_exclude = ['@example.com', '@test.com', '@mailinator.com' ....]
User.objects.exclude(email__regex = "|".join(emails_to_exclude))

我不知道这个查询的效率。

这不适用于 SQLite,因为它没有内置的正则表达式支持。


2
投票

实现此目的的另一种方法:

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)

1
投票

您可以循环遍历电子邮件并构建一个Q 对象。事实上,如果你聪明的话,你也许可以做 1-liner。

User.objects.exclude(bitwise_or_function[Q(email__endswith=e) for e in emails_to_exclude])

类似这样的事情。我不记得按位或整个列表的函数,我的 Python 生锈了。


1
投票

这应该适用于最新版本的 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 
    ) ) )
)

0
投票

由于这是专门针对电子邮件的,因此我只在过滤器中使用

contains
endswith
更具体,但由于电子邮件字符串不能包含多个
@
符号,因此以下方法有效。

emails_to_exclude = ['@example.com', '@test.com', '@mailinator.com' ....]
Users.objects.exclude(email__contains=emails_to_exclude)

-2
投票

我更改了排除输入,使其成为

set
并且没有“@”。否则,这应该可以达到你想要的效果。

>>> emails = ['[email protected]', '[email protected]', '[email protected]']
>>> excludes = {'example.com', 'test.com', 'mailinator.com'}
>>> [email for email in emails if email.split('@')[-1] not in excludes]
['[email protected]']
© www.soinside.com 2019 - 2024. All rights reserved.