Python/Django 中的电子邮件白名单/黑名单

在 Django 应用中,需要控制哪些电子邮件地址可以向某用户帐户发帖。用户可以根据需要将地址列入白名单或黑名单。

任何未指定地址既可按消息处理,也可按白名单或黑名单进行默认处理(同样由用户指定)。

为了实现该功能,设计了以下 Django 模型,我们想请教各位,这是否是一种好的做法?或者,我们是否应该为每个用户的配置文件模型添加一个白名单和黑名单字段?

class knownEmail(models.Model):
    # 允许或禁止地址的用户,并非该地址所属用户...
    relatedUser = models.ManyToManyField(User)
    email = models.EmailField()

class whiteList(knownEmail):
    pass

class blackList(knownEmail):
    pass

然后,我们可以进行类似以下操作:

def checkPermission(user, emailAddress):
    "Check if 'emailAddress' is allowed to post content to 'user's profile"
    if whiteList.objects.filter(relatedUser=user, email=emailAddress):
        return True
    elif blackList.objects.filter(relatedUser=user, email=emailAddress):
        return False
    else:
        return None

是否还有更好的方法?


2. 解决方案

回答 1:

一位网友建议将代码重构,以便将两个列表都包含在一个模型中。

class PermissionList(models.Model):
    setter = models.ManyToManyField(User)
    email = models.EmailField(unique=True) #don't want conflicting results
    permission = models.BooleanField()

然后,我们的列表将变为:

# whitelist
PermissionList.objects.filter(permission=True)
# blacklist
PermissionList.objects.filter(permission=False)

为了检查特定用户,只需给该模型添加一些函数:

class PermissionList(...):
    ...
    @classmethod
    def is_on_whitelist(email):
        return PermissionList.objects.filter(email=email, permission=True).count() > 0

    @classmethod
    def is_on_blacklist(email):
        return PermissionList.objects.filter(email=email, permission=False).count() > 0

    @classmethod
    def has_permission(email):
        if PermissionList.is_on_whitelist(email):
            return True
        if PermissionList.is_on_blacklist(email):
            return False
        return None

将所有内容放在同一个地方简单得多,并且我们可以更轻松地完成更有趣的查询。

回答 2:

另一位网友建议,代码中对类的区分利用得不够充分。

具体来说,这两个类的行为并没有什么差异。由于这两个类具有完全相同的方法,因此首先就不清楚为什么将它们分为两个不同的类。如果它们具有不同的方法,那么我们提供的解决方案是不错的。

但是,如果它们没有不同的方法,我们或许需要考虑为 KnownEmail 的两个子集提供一个自定义管理器。

class WhiteList( models.Manager ):
    def get_query_set( self ):
        return super( WhiteList, self ).get_query_set().filter( status='W' )

class BlackList( models.Manager ):
    def get_query_set( self ):
        return super( BlackList, self ).get_query_set().filter( status='B' )

class KnownEmail( models.Model ):
    relatedUser = models.ForeignKey(User)
    email = models.EmailField()
    status = models.CharField( max_length=1, choices=LIST_CHOICES )
    objects = models.Manager() # default manager shows all lists
    whiteList= WhiteList() # KnownEmail.whiteList.all() is whitelist subset
    blackList= BlackList() # KnownEmail.blackList.all() is blackList subset
  • 7
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值