【问题标题】:Django filter by conditionDjango按条件过滤
【发布时间】:2018-11-12 15:51:09
【问题描述】:

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

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 django django-queryset django-orm django-filter


    【解决方案1】:

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

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

    employees_by_letter = [
        employees.filter(name__istartswith=letter)
        for letter in alphabet
    ]

    这是一个列表推导式,它将为每个letter in 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 实例列表:带有名称的 Employees以那封信开头。这意味着我们只对数据库执行一个查询。然而 Django 查询集是懒惰的,所以如果你打算只获取几个查询集,那么前者可能更有效。

    【讨论】:

      猜你喜欢
      • 2016-04-22
      • 2017-07-25
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-12-05
      • 2018-08-09
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多