Python Django中的优雅析取范式

Python Django中的优雅析取范式,python,django,Python,Django,假设我已经定义了这个模型: class Identifier(models.Model): user = models.ForeignKey(User) key = models.CharField(max_length=64) value = models.CharField(max_length=255) 每个用户都有多个标识符,每个标识符都有一个键和一个值。我100%确定我想保持这样的设计,我这样做是有外部原因的,所以我不想改变这个 我想开发一个这样的函数: de

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

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中指定的键=值对之一的所有用户。下面是一个示例用法:

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的新手,所以我不知道该怎么做。下面是我的函数,我完全相信这不是最好的方法:)

有什么想法吗?:)


谢谢

谢谢!做这件事的好方法。不过我不得不稍微调整一下。正如您所写的,对我来说,它导致了“SyntaxError:Generator表达式如果不是唯一的参数,则必须用括号括起来”。我将第二行改为“q=reduce(operator.or)(q(identifier\uu key=k,identifier\uu value=v)for(k,v)in kwargs.iteritems())”,它工作得很好。实际上,还需要一个小的修改,才能使它完全按照我上面指定的方式运行。您需要将最后一行更改为“return User.objects.filter(q).distinct()
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)
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)