Django中优雅的析取范式

时间:2010-05-28 00:40:54

标签: python django

假设我已经定义了这个模型:

class Identifier(models.Model):
    user = models.ForeignKey(User)
    key = models.CharField(max_length=64)
    value = models.CharField(max_length=255)

每个用户都有多个标识符,每个标识符都包含一个键和一个值。我100%肯定我想保持这样的设计,有外部原因我为什么这样做,我不会在这里,所以我不想改变它。

我想开发一种这样的功能:

def get_users_by_identifiers(**kwargs):
    # something goes here
    return users

该函数将返回具有** kwargs中指定的key = value对之一的所有用户。以下是一个示例用法:

get_users_by_identifiers(a=1, b=2)

这应该返回a = 1或b = 2的所有用户。我注意到我设置它的方式,这相当于一个析取的正常形式...... SQL查询将类似于:

SELECT DISTINCT(user_id) FROM app_identifier 
    WHERE (key = "a" AND value = "1") OR (key = "b" AND value = "2") ...

我觉得必须采用一些优雅的方式来获取** kwargs输入并在其上执行一个Django过滤器,只需1-2行,就可以产生这个结果。我是Django的新手,所以我不知道怎么做。现在这是我的功能,我完全相信这不是最好的方法:)

def get_users_by_identifiers(**identifiers):
    users = []
    for key, value in identifiers.items():
        for identifier in Identifier.objects.filter(key=key, value=value):
            if not identifier.user in users:
                users.append(identifier.user)

    return users

有什么想法吗? :)

谢谢!

1 个答案:

答案 0 :(得分:1)

def get_users_by_identifiers(**kwargs):
    q = reduce(operator.or_, Q(identifier__key=k, identifier__value=v)
        for (k, v) in kwargs.iteritems())
    return User.objects.filter(q)