在Django ORM中过滤order_by关系

问题描述 投票:0回答:2

[在下面,产品通过贡献者有许多作者,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?
)
django django-models django-orm
2个回答
0
投票

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

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'
    )

0
投票

您可以通过注释子查询执行此操作:

  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”,则我们无法控制将哪个订购者用于订购-我们将获得首先返回的那个数据库。您可以在order_by上添加contributors_for_ordering子句来处理。

© www.soinside.com 2019 - 2024. All rights reserved.