【问题标题】:filtering the order_by relationship in Django ORM在 Django ORM 中过滤 order_by 关系
【发布时间】:2015-04-30 16:25:30
【问题描述】:

在下面,产品通过贡献者有许多作者,contributor.role_code 定义了对产品的确切贡献类型。 Django ORM 是否可以过滤下面 order_by() 方法引用的贡献者?例如。我只想订购 contributor.role_code in ['A01', 'B01'] 等贡献者的产品。

Product.objects.filter(
    product_type__name=choices.PRODUCT_BOOK
).order_by(
    'contributor__writer__last_name'    # filter which contributors it uses?
)

【问题讨论】:

  • 我不明白你在问什么。您的意思是要获取由contributor.role_code 过滤的产品列表吗?
  • 不是contributor.role_code过滤的产品列表,而是按产品类型过滤的产品列表,然后filterlimit order_by 范围为角色代码为 A01,然后是 B01 的贡献者。
  • yekta 是对的。我的意思是我可以根据角色代码为 A01 和 B01 的贡献者的作者的姓氏来订购产品,而不是其他会出现在该订单中的贡献者吗?
  • filter/limit django order_by 的可能重复项

标签: django django-models django-orm


【解决方案1】:

您可以通过注释子查询来做到这一点:

  1. 定义代表我们想要订购的东西的子查询
  2. 用子查询注释原始查询集
  3. 按注释排序。
contributors_for_ordering = Contributor.objects.filter( # 1
    product=OuterRef('pk'),
    role_code__in=['A01', 'B01'],
).values('writer__last_name')

queryset = Product.objects.filter(
    product_type__name=choices.PRODUCT_BOOK
).annotate( # 2
    writer_last_name=Subquery(contributors_for_ordering[:1])  # Slice [:1] to ensure a single result
).order_by( # 3
    'writer_last_name'
)

但是请注意,这里有一个潜在的怪癖。如果产品的贡献者同时具有“A01”和“B01”,我们无法控制哪个将用于订购——我们将获得数据库首先返回的那个。您可以在contributors_for_ordering 中添加order_by 子句来处理。

【讨论】:

    【解决方案2】:

    要过滤特定值,首先建立您的接受值列表:

    accepted_values = ['A01', 'B01']
    

    然后过滤此列表中的值:

    Product.objects.filter(
            product_type__name=choices.PRODUCT_BOOK
        ).filter(
            contributor__role_code__in=accepted_values
        ).order_by(
            'contributor__writer__last_name'
        )
    

    【讨论】:

    • 不幸的是,每个产品有很多贡献者,所以这并不能解决问题——我试图确保在 order_by() 调用中它是基于 A01 的贡献者的排序和 B01,而不是其他贡献者。这将过滤产品,但不会影响用于订购 IINM 的贡献者。
    猜你喜欢
    • 2019-07-06
    • 2015-04-30
    • 1970-01-01
    • 1970-01-01
    • 2014-01-02
    • 1970-01-01
    • 1970-01-01
    • 2018-11-18
    相关资源
    最近更新 更多