python - Django 按条件过滤

标签 python django django-queryset django-orm django-filter

我有一个查询集,我想按字母顺序对其进行分页。

employees = Employee.nodes.order_by('name')

我想将员工姓名 name[0] 的首字母与我正在迭代的字母进行比较。 - 但我不知道如何根据应用于我的属性的条件进行过滤。

employees_by_letter = []      

for letter in alphabet: 
    employees_by_this_letter = employees.filter(name[0].lower()=letter)
    employees_by_letter.append(employees_by_this_letter)

  """error -- SyntaxError: keyword can't be an expression"""

我想我可以遍历每个员工对象并为他们的第一个字母附加一个值...但必须有更好的方法。

最佳答案

这是 Python,在 Python 中参数名称是标识符。您不能将某种表达式放入其中。

不过,Django 有一些方法可以进行高级过滤。在您的情况下,您想使用 __istartswith过滤器:

employees_by_letter = [
    employees.filter(name<b>__istartswith</b>=letter)
    for letter in alphabet
]

这是一个列表理解,它将生成这样的内容,即对于每个 alphabet 中的字母,对应的查询集都在列表中。

但是请注意,由于您最终会获取每个元素,因此我实际上建议迭代(或执行 groupby 示例)。

喜欢:

from django.db.models.functions import Lower
fromiteratools import groupby

employees_by_letter = {
    k: list(v)
    for k, v in groupby(
        Employee.annotate(lowname=Lower('name')).nodes.order_by('lowname'),
        lambda x: x.lowname[:1]
    )
}

这将构建一个以小写字母(或空字符串,如果有空名称的字符串)作为键的字典,并且这些都映射到 Employee 实例列表:Employee 的名字以该字母开头。所以这意味着我们只对数据库执行一次查询。然而,Django 查询集是惰性的,所以如果您打算只真正获取一些查询集,那么前者会更高效。

关于python - Django 按条件过滤,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/50661463/

相关文章:

python - 补丁不模拟模块

python - 在引发异常时重试 Django View 的最简单方法是什么?

python - Django:如何允许可疑文件操作/复制文件

python sqlalchemy - 将表映射到特定的数据结构

django - 如何使用 Django 中间件将值传递给每个 View

python - 如何在 Django 查询集过滤中执行不等于?

django - 没有关系时计数并返回零的注释

python - 如何从ManyToOne表中只获取一个对象,而不是查询集?

python - Numpy:获取二维数组最小值的列索引和行索引

python - 在 Django 中缓存站点地图