Django中的优雅析取范式

2 投票
1 回答
565 浏览
提问于 2025-04-15 23:16

假设我定义了一个模型:

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

每个用户会有多个标识符,每个标识符都有一个键和一个值。我非常确定我想保持这样的设计,原因比较复杂,这里就不详细说明了,所以我不想改变这个设计。

我想开发一个这样的函数:

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") ...

我觉得应该有一种优雅的方法,可以用1-2行代码来处理**kwargs的输入,并在Django中进行过滤,以得到这个结果。不过我对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 个回答

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)

撰写回答